Update `codebox` macro
authorMatthias Schmidt <gravatronics@live.com>
Fri, 23 Apr 2021 13:42:31 +0000 (15:42 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Fri, 23 Apr 2021 13:42:31 +0000 (15:42 +0200)
… to also support inline contents.

34 files changed:
docs/javascript/typescript.md
docs/package/package-xml.md
docs/package/pip/acl-option.md
docs/package/pip/acp-menu.md
docs/package/pip/acp-search-provider.md
docs/package/pip/bbcode.md
docs/package/pip/box.md
docs/package/pip/clipboard-action.md
docs/package/pip/core-object.md
docs/package/pip/cronjob.md
docs/package/pip/event-listener.md
docs/package/pip/language.md
docs/package/pip/media-provider.md
docs/package/pip/menu-item.md
docs/package/pip/menu.md
docs/package/pip/object-type-definition.md
docs/package/pip/object-type.md
docs/package/pip/option.md
docs/package/pip/page.md
docs/package/pip/pip.md
docs/package/pip/smiley.md
docs/package/pip/sql.md
docs/package/pip/template-listener.md
docs/package/pip/user-menu.md
docs/package/pip/user-notification-event.md
docs/package/pip/user-profile-menu.md
docs/php/api/cronjobs.md
docs/php/gdpr.md
docs/tutorial/series/part_1.md
docs/tutorial/series/part_2.md
docs/tutorial/series/part_3.md
docs/tutorial/series/part_4.md
docs/tutorial/series/part_5.md
main.py

index 64327df67aea0c5717d6cd207363e24ec2f9b24e..2e77a08f0dd5cea49adbd285ea3d08900d69c47f 100644 (file)
@@ -7,9 +7,9 @@ To consume the types of WoltLab Suite, you will need to install the `@woltlab/wc
 A full `package.json` that includes WoltLab Suite, TypeScript, eslint and Prettier could look like the following.
 
 {jinja{ codebox(
-    "json",
-    "typescript/package.json",
-    "package.json"
+  title="package.json",
+  language="json",
+  filepath="typescript/package.json"
 ) }}
 
 After installing the types using npm, you will also need to configure `tsconfig.json` to take the types into account.
@@ -17,9 +17,9 @@ To do so, you will need to add them to the `compilerOptions.paths` option.
 A complete `tsconfig.json` file that matches the configuration of WoltLab Suite could look like the following.
 
 {jinja{ codebox(
-    "json",
-    "typescript/tsconfig.json",
-    "tsconfig.json"
+  title="tsconfig.json",
+  language="json",
+  filepath="typescript/tsconfig.json"
 ) }}
 
 After this initial set-up, you would place your TypeScript source files into the `ts/` folder of your project.
@@ -32,30 +32,30 @@ The current configuration of these tools is as follows.
 It is recommended to re-use this configuration as is.
 
 {jinja{ codebox(
-    "yml",
-    "typescript/.prettierrc",
-    ".prettierrc"
+  title=".prettierrc",
+  language="yml",
+  filepath="typescript/.prettierrc"
 ) }}
 
 {jinja{ codebox(
-    "javascript",
-    "typescript/.eslintrc.js",
-    ".eslintrc.js"
+  title=".eslintrc.js",
+  language="javascript",
+  filepath="typescript/.eslintrc.js"
 ) }}
 
 {jinja{ codebox(
-    "gitignore",
-    "typescript/.eslintignore",
-    ".eslintignore"
+  title=".eslintignore",
+  language="gitignore",
+  filepath="typescript/.eslintignore"
 ) }}
 
 This `.gitattributes` configuration will automatically collapse the generated JavaScript target files in GitHub’s Diff view.
 You will not need it if you do not use git or GitHub.
 
 {jinja{ codebox(
-    "gitattributes",
-    "typescript/.gitattributes",
-    ".gitattributes"
+  title=".gitattributes",
+  language="gitattributes",
+  filepath="typescript/.gitattributes"
 ) }}
 
 ## Writing a simple module
@@ -67,17 +67,17 @@ WoltLab Suite’s modules can be imported using the standard ECMAScript module i
 The public API of the module can also be exported using the standard ECMAScript module export syntax.
 
 {jinja{ codebox(
-    "typescript",
-    "typescript/Example.ts",
-    "ts/Example.ts"
+  title="ts/Example.ts",
+  language="typescript",
+  filepath="typescript/Example.ts"
 ) }}
 
 This simple example module will compile to plain JavaScript that is compatible with the AMD loader that is used by WoltLab Suite.
 
 {jinja{ codebox(
-    "javascript",
-    "typescript/Example.js",
-    "files/js/Example.js"
+  title="files/js/Example.js",
+  language="javascript",
+  filepath="typescript/Example.js"
 ) }}
 
 Within templates it can be consumed as follows.
index 06a1528538203d7a4ca6a6ff8dd33bad06287afa..d26557d8b86504f514d5115c52daec6f0c4f9a0f 100644 (file)
@@ -6,9 +6,9 @@ It provides the meta data (e.g. package name, description, author) and the instr
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/package.xml",
-    "package.xml"
+  title="package.xml",
+  language="xml",
+  filepath="package/package.xml"
 ) }}
 
 
index c54fa9c199adf65eecea0260435af01a18df8544..1450afecca4a4cb5b72893bcb8978925fdcb1473 100644 (file)
@@ -29,7 +29,7 @@ The name of the acl object type (of the object type definition `com.woltlab.wcf.
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/aclOption.xml",
-    "aclOption.xml"
+  title="aclOption.xml",
+  language="xml",
+  filepath="package/pip/aclOption.xml"
 ) }}
index 6f185d4152eabdc540970a63b144ae5cb7d3fbb9..893101681c5c3795e041a40a9f643aa02f959bdf 100644 (file)
@@ -49,7 +49,7 @@ The permissions element can contain a comma-separated list of permissions of whi
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/acpMenu.xml",
-    "acpMenu.xml"
+  title="acpMenu.xml",
+  language="xml",
+  filepath="package/pip/acpMenu.xml"
 ) }}
index 45543b0be08317b2ae5a402e38ac43fcc20cb0db..91501f746e6d0cb00aebd70cdb0583004403b545 100644 (file)
@@ -20,7 +20,7 @@ Determines at which position of the search result list the provided results are
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/acpSearchProvider.xml",
-    "acpSearchProvider.xml"
+  title="acpSearchProvider.xml",
+  language="xml",
+  filepath="package/pip/acpSearchProvider.xml"
 ) }}
index f4fed2b1061c8a709ab4930527a1bc73e8e2487c..451e6a0ab2385ef44990485fd069a775a224571a 100644 (file)
@@ -86,7 +86,7 @@ Specifies whether the text content of the BBCode should become this attribute's
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/bbcode.xml",
-    "bbcode.xml"
+  title="bbcode.xml",
+  language="xml",
+  filepath="package/pip/bbcode.xml"
 ) }}
index d90a0cb3e8a520c65579e83c579cb763ecfcb481..0039bdc965d4d013f42cbe11d1d9c8e9cc11f741 100644 (file)
@@ -76,7 +76,7 @@ The content that should be used to populate the box, only used and required if t
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/box.xml",
-    "box.xml"
+  title="box.xml",
+  language="xml",
+  filepath="package/pip/box.xml"
 ) }}
index e2dba6b68970bd08dbea254b7b54243208f56c0c..14e56f4ae3148c3a96be79787e989e080f9125b3 100644 (file)
@@ -25,7 +25,7 @@ Determines at which position of the clipboard action list the action is shown.
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/clipboardAction.xml",
-    "clipboardAction.xml"
+  title="clipboardAction.xml",
+  language="xml",
+  filepath="package/pip/clipboardAction.xml"
 ) }}
index 26f41f792a7a3326f55f398320f501f70173ebb1..c636bb833aa5641d69cf778b2b602399bad8eefe 100644 (file)
@@ -13,9 +13,9 @@ The fully qualified class name of the class.
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/coreObject.xml",
-    "coreObject.xml"
+  title="coreObject.xml",
+  language="xml",
+  filepath="package/pip/coreObject.xml"
 ) }}
 
 This object can be accessed in templates via `$__wcf->getExampleHandler()` (in general: the method name begins with `get` and ends with the unqualified class name).
index ff626f7104468e473d05c88b9d6ba10fef1511ba..179d4aff88ac3d7ea91c8065e458b52e681bc3d0 100644 (file)
@@ -40,7 +40,7 @@ The options element can contain a comma-separated list of options of which at le
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/cronjob.xml",
-    "cronjob.xml"
+  title="cronjob.xml",
+  language="xml",
+  filepath="package/pip/cronjob.xml"
 ) }}
index 9078509a93696ef1025556d6a6f3f3bf5677cd1e..de2da7f5f400f89abb888a7e5885e5d3518860b7 100644 (file)
@@ -56,7 +56,7 @@ The permissions element can contain a comma-separated list of permissions of whi
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/eventListener.xml",
-    "eventListener.xml"
+  title="eventListener.xml",
+  language="xml",
+  filepath="package/pip/eventListener.xml"
 ) }}
index 5cc816b717d4b87a60129e974a594fac5741e03b..cf4fb5d170dfdff143784aea853c2a48e8578655 100644 (file)
@@ -24,7 +24,7 @@ The text content of the `<item>` node is the value of the language item. Languag
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/en.xml",
-    "language/en.xml"
+  title="language/en.xml",
+  language="xml",
+  filepath="package/pip/en.xml"
 ) }}
index ef163ba5284164dc4a3e4fbfa3a74b957eb722cf..9d43f53698f94503f9c29a1c5af5416576b8bb0c 100644 (file)
@@ -33,7 +33,7 @@ Replacement HTML that gets populated using the captured matches in `<regex>`, va
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/mediaProvider.xml",
-    "mediaProvider.xml"
+  title="mediaProvider.xml",
+  language="xml",
+  filepath="package/pip/mediaProvider.xml"
 ) }}
index 13fe829fe8d4ef5bd4b04aa2b6f9bffad5c49b1a..e2adcb57dfabe36f413786e2269181e102152086 100644 (file)
@@ -23,7 +23,7 @@ The page that the link should point to, requires the internal identifier set by
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/menuItem.xml",
-    "menuItem.xml"
+  title="menuItem.xml",
+  language="xml",
+  filepath="package/pip/menuItem.xml"
 ) }}
index 3cd311cfc618b2c5c13b2487e93f2820ed0ea4ee..d15510cb3df2ac390a17d90a000a8059559ff117 100644 (file)
@@ -25,7 +25,7 @@ The following elements of the [box PIP](box.md) are supported, please refer to t
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/menu.xml",
-    "menu.xml"
+  title="menu.xml",
+  language="xml",
+  filepath="package/pip/menu.xml"
 ) }}
index 3ca05db5b38fd9f83c5500f7196921987c5dcbf9..ff52539cb8da1a69ccd41f129869a5349f05127a 100644 (file)
@@ -23,7 +23,7 @@ The name of the PHP interface [objectTypes](object-type.md) have to implement.
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/objectTypeDefinition.xml",
-    "objectTypeDefinition.xml"
+  title="objectTypeDefinition.xml",
+  language="xml",
+  filepath="package/pip/objectTypeDefinition.xml"
 ) }}
index 3fe1bbb0e76fc4ba4b4ae931a32559d1edc982c7..7664bac59b6cb666a4e3009efc97ed68ebc0a139 100644 (file)
@@ -26,7 +26,7 @@ Refer to the documentation of these for further explanation.
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/objectType.xml",
-    "objectType.xml"
+  title="objectType.xml",
+  language="xml",
+  filepath="package/pip/objectType.xml"
 ) }}
index 07587ec05f402e5908c6b1fc06d5729f74a0438e..ecec76bef17b4d29211fe94c6cd55501abd644f5 100644 (file)
@@ -128,7 +128,7 @@ If you want to provide an optional description of the option, you have to provid
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/option.xml",
-    "option.xml"
+  title="option.xml",
+  language="xml",
+  filepath="package/pip/option.xml"
 ) }}
index 61585cac11bacee6ba23836fd53995d3beded5b4..74ef6fc71369f19b4e46b346abb37b4c06acb2a5 100644 (file)
@@ -75,7 +75,7 @@ The content that should be used to populate the page, only used and required if
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/page.xml",
-    "page.xml"
+  title="page.xml",
+  language="xml",
+  filepath="package/pip/page.xml"
 ) }}
\ No newline at end of file
index b76cb3db7fe93499c680ad05995c107d71f7bd02..9f25a8a45d37a02c59eea0ed78fc1d4a5e781c8a 100644 (file)
@@ -11,7 +11,7 @@ Each package installation plugin is described as an `<pip>` element with a `name
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/packageInstallationPlugin.xml",
-    "packageInstallationPlugin.xml"
+  title="packageInstallationPlugin.xml",
+  language="xml",
+  filepath="package/pip/packageInstallationPlugin.xml"
 ) }}
index dffb4ed64e68cca985255d5e7b68a5e4b8e84eb4..89190fdf1a74a69e80cf6c3fea85be924cb8d9bb 100644 (file)
@@ -33,7 +33,7 @@ Determines at which position of the smiley list the smiley is shown.
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/smiley.xml",
-    "smiley.xml"
+  title="smiley.xml",
+  language="xml",
+  filepath="package/pip/smiley.xml"
 ) }}
index 469df6a57a714449b09a42f5e5f32e9e6647cb08..150eea8ab0356febeeca0194fec6ec32a0bb6653 100644 (file)
@@ -59,7 +59,7 @@ If you really need triggers, you should consider adding them by custom SQL queri
 Example content:
 
 {jinja{ codebox(
-    "sql",
-    "package/pip/install.sql",
-    "install.sql"
+  title="install.sql",
+  language="sql",
+  filepath="package/pip/install.sql"
 ) }}
\ No newline at end of file
index 7f22a5d51bc176af7dcf2224111a09a56291e13e..e41dec119b5cad8b3bbd850a945581d037c3b4c6 100644 (file)
@@ -57,7 +57,7 @@ The permissions element can contain a comma-separated list of permissions of whi
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/templateListener.xml",
-    "templateListener.xml"
+  title="templateListener.xml",
+  language="xml",
+  filepath="package/pip/templateListener.xml"
 ) }}
index 82b3e720cb883f67f1e5348e9440a266f0168e7a..0792e98dd2d48bb18653bbbfd9fa363fe9e4c6f3 100644 (file)
@@ -56,7 +56,7 @@ the class has to implement the `wcf\system\menu\user\IUserMenuItemProvider` inte
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/userMenu.xml",
-    "userMenu.xml"
+  title="userMenu.xml",
+  language="xml",
+  filepath="package/pip/userMenu.xml"
 ) }}
index eef427a8cd6bc775a447678df1f1d1f7c024553a..ea721aabb27b53a4b88bca4f7c4107d9467ff1a4 100644 (file)
@@ -43,7 +43,7 @@ The permissions element can contain a comma-separated list of permissions of whi
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/userNotificationEvent.xml",
-    "userNotificationEvent.xml"
+  title="userNotificationEvent.xml",
+  language="xml",
+  filepath="package/pip/userNotificationEvent.xml"
 ) }}
index f39fc3da032881a6c93690cde9bcdb79b99d4c65..5b36b60889d14e7270280589aeea910c15f26f8b 100644 (file)
@@ -32,7 +32,7 @@ The permissions element can contain a comma-separated list of permissions of whi
 ## Example
 
 {jinja{ codebox(
-    "xml",
-    "package/pip/userProfileMenu.xml",
-    "userProfileMenu.xml"
+  title="userProfileMenu.xml",
+  language="xml",
+  filepath="package/pip/userProfileMenu.xml"
 ) }}
index 18fd6ffd65b36c26c38255dfc09b48beebc2d28e..d2757e85f692f44eb0f59968405a1c8c9caaf4c3 100644 (file)
@@ -10,9 +10,9 @@ This page focuses on the technical aspects of cronjobs, [the cronjob package ins
 ## Example
 
 {jinja{ codebox(
-    "php",
-    "php/api/cronjobs/LastActivityCronjob.class.php",
-    "files/lib/system/cronjob/LastActivityCronjob.class.php"
+  title="files/lib/system/cronjob/LastActivityCronjob.class.php",
+  language="php",
+  filepath="php/api/cronjobs/LastActivityCronjob.class.php"
 ) }}
 
 
index 243c71dbed277e23d0d49362607c70bd7be8c1ba..4f1faf33ba98dbfe15fece35894cbb829de7fe7d 100644 (file)
@@ -22,9 +22,9 @@ has been dumped to the `$data` property.
 ### Example code
 
 {jinja{ codebox(
-    "php",
-    "php/gdpr/MyUserExportGdprActionListener.class.php",
-    "files/lib/system/event/listener/MyUserExportGdprActionListener.class.php"
+  title="files/lib/system/event/listener/MyUserExportGdprActionListener.class.php",
+  language="php",
+  filepath="php/gdpr/MyUserExportGdprActionListener.class.php"
 ) }}
 
 ### `$data`
index 0f2491e12cb6cdd15650467134082da1b381e1a4..79fd3d20865e3717e166fa65e7bebc2f15f834a6 100644 (file)
@@ -85,9 +85,9 @@ Thus, the database table we will store the people in only contains three columns
 The first file for our package is the `install_com.woltlab.wcf.people.php` file used to create such a database table during package installation:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/acp/database/install_com.woltlab.wcf.people.php",
-    "files/acp/database/install_com.woltlab.wcf.people.php"
+  title="files/acp/database/install_com.woltlab.wcf.people.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/acp/database/install_com.woltlab.wcf.people.php"
 ) }}
 
 ### Database Object
@@ -97,9 +97,9 @@ The first file for our package is the `install_com.woltlab.wcf.people.php` file
 In our PHP code, each person will be represented by an object of the following class:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/data/person/Person.class.php",
-    "files/lib/data/person/Person.class.php"
+  title="files/lib/data/person/Person.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/data/person/Person.class.php"
 ) }}
 
 The important thing here is that `Person` extends `DatabaseObject`.
@@ -111,9 +111,9 @@ an action class, an editor class and a list class.
 #### `PersonAction`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/data/person/PersonAction.class.php",
-    "files/lib/data/person/PersonAction.class.php"
+  title="files/lib/data/person/PersonAction.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/data/person/PersonAction.class.php"
 ) }}
 
 This implementation of `AbstractDatabaseObjectAction` is very basic and only sets the `$permissionsDelete` and `$requireACP` properties.
@@ -125,9 +125,9 @@ We will later use the [userGroupOption package installation plugin](../../packag
 #### `PersonEditor`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/data/person/PersonEditor.class.php",
-    "files/lib/data/person/PersonEditor.class.php"
+  title="files/lib/data/person/PersonEditor.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/data/person/PersonEditor.class.php"
 ) }}
 
 This implementation of `DatabaseObjectEditor` fulfills the minimum requirement for a database object editor:
@@ -136,9 +136,9 @@ setting the static `$baseClass` property to the database object class name.
 #### `PersonList`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/data/person/PersonList.class.php",
-    "files/lib/data/person/PersonList.class.php"
+  title="files/lib/data/person/PersonList.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/data/person/PersonList.class.php"
 ) }}
 
 Due to the default implementation of `DatabaseObjectList`, our `PersonList` class just needs to extend it and everything else is either automatically set by the code of `DatabaseObjectList` or, in the case of properties and methods, provided by that class.
@@ -164,9 +164,9 @@ We need to create three menu items:
 1. a fourth level menu item for the form to add new people.
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-1/acpMenu.xml",
-    "acpMenu.xml"
+  title="acpMenu.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-1/acpMenu.xml"
 ) }}
 
 We choose `wcf.acp.menu.link.content` as the parent menu item for the first menu item `wcf.acp.menu.link.person` because the people we are managing is just one form of content.
@@ -179,9 +179,9 @@ To list the people in the ACP, we need a `PersonListPage` class and a `personLis
 #### `PersonListPage`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/acp/page/PersonListPage.class.php",
-    "files/lib/data/person/PersonListPage.class.php"
+  title="files/lib/data/person/PersonListPage.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/acp/page/PersonListPage.class.php"
 ) }}
 
 As WoltLab Suite Core already provides a powerful default implementation of a sortable page, our work here is minimal:
@@ -195,9 +195,9 @@ As WoltLab Suite Core already provides a powerful default implementation of a so
 #### `personList.tpl`
 
 {jinja{ codebox(
-    "smarty",
-    "tutorial/tutorial-series/part-1/acptemplates/personList.tpl",
-    "acptemplates/personList.tpl"
+  title="acptemplates/personList.tpl",
+  language="smarty",
+  filepath="tutorial/tutorial-series/part-1/acptemplates/personList.tpl"
 ) }}
 
 We will go piece by piece through the template code:
@@ -230,9 +230,9 @@ Like the person list, the form to add new people requires a controller class and
 #### `PersonAddForm`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/acp/form/PersonAddForm.class.php",
-    "files/lib/acp/form/PersonAddForm.class.php"
+  title="files/lib/acp/form/PersonAddForm.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/acp/form/PersonAddForm.class.php"
 ) }}
 
 The properties here consist of three types:
@@ -249,9 +249,9 @@ Because of using form builder, we only have to set up the two form fields for en
 #### `personAdd.tpl`
 
 {jinja{ codebox(
-    "smarty",
-    "tutorial/tutorial-series/part-1/acptemplates/personAdd.tpl",
-    "acptemplates/personAdd.tpl"
+  title="acptemplates/personAdd.tpl",
+  language="smarty",
+  filepath="tutorial/tutorial-series/part-1/acptemplates/personAdd.tpl"
 ) }}
 
 We will now only concentrate on the new parts compared to `personList.tpl`:
@@ -266,9 +266,9 @@ As mentioned before, for the form to edit existing people, we only need a new co
 #### `PersonEditForm`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/acp/form/PersonEditForm.class.php",
-    "files/lib/acp/form/PersonEditForm.class.php"
+  title="files/lib/acp/form/PersonEditForm.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/acp/form/PersonEditForm.class.php"
 ) }}
 
 In general, edit forms extend the associated add form so that the code to read and to validate the input data is simply inherited.
@@ -288,9 +288,9 @@ This page should also be directly linked in the main menu.
 First, let us register the page with the system because every front end page or form needs to be explicitly registered using the [page package installation plugin](../../package/pip/page.md):
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-1/page.xml",
-    "page.xml"
+  title="page.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-1/page.xml"
 ) }}
 
 For more information about what each of the elements means, please refer to the [page package installation plugin page](../../package/pip/page.md).
@@ -300,9 +300,9 @@ For more information about what each of the elements means, please refer to the
 Next, we register the menu item using the [menuItem package installation plugin](../../package/pip/menu-item.md):
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-1/menuItem.xml",
-    "menuItem.xml"
+  title="menuItem.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-1/menuItem.xml"
 ) }}
 
 Here, the import parts are that we register the menu item for the main menu `com.woltlab.wcf.MainMenu` and link the menu item with the page `com.woltlab.wcf.people.PersonList`, which we just registered.
@@ -316,9 +316,9 @@ This is no problem because the qualified names of the classes differ and the fil
 #### `PersonListPage`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-1/files/lib/page/PersonListPage.class.php",
-    "files/lib/page/PersonListPage.class.php"
+  title="files/lib/page/PersonListPage.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-1/files/lib/page/PersonListPage.class.php"
 ) }}
 
 This class is almost identical to the ACP version.
@@ -329,9 +329,9 @@ In the front end, we explicitly set the `$defaultSortField` so that the people l
 #### `personList.tpl`
 
 {jinja{ codebox(
-    "smarty",
-    "tutorial/tutorial-series/part-1/templates/personList.tpl",
-    "templates/personList.tpl"
+  title="templates/personList.tpl",
+  language="smarty",
+  filepath="tutorial/tutorial-series/part-1/templates/personList.tpl"
 ) }}
 
 If you compare this template to the one used in the ACP, you will recognize similar elements like the `.paginationTop` element, the `p.info` element if no people exist, and the `.contentFooter` element.
@@ -357,9 +357,9 @@ Now, let us take a closer look at the differences:
 We have already used the `admin.content.canManagePeople` permissions several times, now we need to install it using the [userGroupOption package installation plugin](../../package/pip/user-group-option.md):
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-1/userGroupOption.xml",
-    "userGroupOption.xml"
+  title="userGroupOption.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-1/userGroupOption.xml"
 ) }}
 
 We use the existing `admin.content` user group option category for the permission as the people are “content” (similar the the ACP menu item).
@@ -374,9 +374,9 @@ Lastly, we need to create the `package.xml` file.
 For more information about this kind of file, please refer to [the `package.xml` page](../../package/package-xml.md).
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-1/package.xml",
-    "package.xml"
+  title="package.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-1/package.xml"
 ) }}
 
 As this is a package for WoltLab Suite Core 3, we need to require it using `<requiredpackage>`.
index 1d3c1f1b54d548260ce511f511030cf1f135bacd..047b8c61d14c3bdf3165b8092da784401ce9b9a5 100644 (file)
@@ -66,9 +66,9 @@ The existing model of a person only contains the person’s first name and their
 To add the birthday to the model, we need to create an additional database table column using the [`database` package installation plugin](../../package/pip/database.md):
 
 {jinja{ codebox(
-    "sql",
-    "tutorial/tutorial-series/part-2/files/acp/database/install_com.woltlab.wcf.people.birthday.php",
-    "files/acp/database/install_com.woltlab.wcf.people.birthday.php"
+  title="files/acp/database/install_com.woltlab.wcf.people.birthday.php",
+  language="sql",
+  filepath="tutorial/tutorial-series/part-2/files/acp/database/install_com.woltlab.wcf.people.birthday.php"
 ) }}
 
 If we have a [`Person` object](part_1.md#person), this new property can be accessed the same way as the `personID` property, the `firstName` property, or the `lastName` property from the base package: `$person->birthday`.
@@ -79,9 +79,9 @@ If we have a [`Person` object](part_1.md#person), this new property can be acces
 To set the birthday of a person, we only have to add another form field with an event listener:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-2/files/lib/system/event/listener/BirthdayPersonAddFormListener.class.php",
-    "files/lib/system/event/listener/BirthdayPersonAddFormListener.class.php"
+  title="files/lib/system/event/listener/BirthdayPersonAddFormListener.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-2/files/lib/system/event/listener/BirthdayPersonAddFormListener.class.php"
 ) }}
 
 registered via
@@ -104,15 +104,15 @@ It is important to set `<inherit>1</inherit>` so that the event listener is also
 The language item `wcf.person.birthday` used in the label is the only new one for this package:
 
 {jinja{ codebox(
-    "sql",
-    "tutorial/tutorial-series/part-2/language/de.xml",
-    "language/de.xml"
+  title="language/de.xml",
+  language="sql",
+  filepath="tutorial/tutorial-series/part-2/language/de.xml"
 ) }}
 
 {jinja{ codebox(
-    "sql",
-    "tutorial/tutorial-series/part-2/language/en.xml",
-    "language/en.xml"
+  title="language/en.xml",
+  language="sql",
+  filepath="tutorial/tutorial-series/part-2/language/en.xml"
 ) }}
 
 
@@ -127,9 +127,9 @@ To add a birthday column to the person list page in the ACP, we need three parts
 The first part is a very simple class:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-2/files/lib/system/event/listener/BirthdaySortFieldPersonListPageListener.class.php",
-    "files/lib/system/event/listener/BirthdaySortFieldPersonListPageListener.class.php"
+  title="files/lib/system/event/listener/BirthdaySortFieldPersonListPageListener.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-2/files/lib/system/event/listener/BirthdaySortFieldPersonListPageListener.class.php"
 ) }}
 
 !!! info "We use `SortablePage` as a type hint instead of `wcf\acp\page\PersonListPage` because we will be using the same event listener class in the front end to also allow sorting that list by birthday."
@@ -156,9 +156,9 @@ To add the birthday as a valid sort field, we use `BirthdaySortFieldPersonListPa
 In the front end, we will now use a template (`__personListBirthdaySortField.tpl`) instead of a directly putting the template code in the `templateListener.xml` file:
 
 {jinja{ codebox(
-    "smarty",
-    "tutorial/tutorial-series/part-2/templates/__personListBirthdaySortField.tpl",
-    "templates/__personListBirthdaySortField.tpl"
+  title="templates/__personListBirthdaySortField.tpl",
+  language="smarty",
+  filepath="tutorial/tutorial-series/part-2/templates/__personListBirthdaySortField.tpl"
 ) }}
 
 !!! info "You might have noticed the two underscores at the beginning of the template file. For templates that are included via template listeners, this is the naming convention we use."
@@ -168,9 +168,9 @@ Putting the template code into a file has the advantage that in the administrato
 To show the birthday, we use the following template code for the `personStatistics` template event, which again makes sure that the birthday is only shown if it is actually set:
 
 {jinja{ codebox(
-    "smarty",
-    "tutorial/tutorial-series/part-2/templates/__personListBirthday.tpl",
-    "templates/__personListBirthday.tpl"
+  title="templates/__personListBirthday.tpl",
+  language="smarty",
+  filepath="tutorial/tutorial-series/part-2/templates/__personListBirthday.tpl"
 ) }}
 
 
@@ -179,9 +179,9 @@ To show the birthday, we use the following template code for the `personStatisti
 The following code shows the `templateListener.xml` file used to install all mentioned template listeners:
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-2/templateListener.xml",
-    "templateListener.xml"
+  title="templateListener.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-2/templateListener.xml"
 ) }}
 
 In cases where a template is used, we simply use the `include` syntax to load the template.
@@ -192,9 +192,9 @@ In cases where a template is used, we simply use the `include` syntax to load th
 There are two event listeners that make `birthday` a valid sort field in the ACP and the front end, respectively, and the third event listener takes care of setting the birthday.
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-2/eventListener.xml",
-    "eventListener.xml"
+  title="eventListener.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-2/eventListener.xml"
 ) }}
 
 
@@ -203,9 +203,9 @@ There are two event listeners that make `birthday` a valid sort field in the ACP
 The only relevant difference between the `package.xml` file of the base page from part 1 and the `package.xml` file of this package is that this package requires the base package `com.woltlab.wcf.people` (see `<requiredpackages>`):
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-2/package.xml",
-    "package.xml"
+  title="package.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-2/package.xml"
 ) }}
 
 ---
index 481702eb206a62d12ebc8a90326b5a8bbf4e156e..6404d58078183ba62efb129947d99d7213533878 100644 (file)
@@ -79,9 +79,9 @@ The complete package will have the following file structure (including the files
 To reduce the number of database queries when different APIs require person objects, we implement a [runtime cache](../../php/api/caches_runtime-caches.md) for people:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-3/files/lib/system/cache/runtime/PersonRuntimeCache.class.php",
-    "files/lib/system/cache/runtime/PersonRuntimeCache.class.php"
+  title="files/lib/system/cache/runtime/PersonRuntimeCache.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-3/files/lib/system/cache/runtime/PersonRuntimeCache.class.php"
 ) }}
 
 
@@ -91,17 +91,17 @@ To allow users to comment on people, we need to tell the system that people supp
 This is done by registering a `com.woltlab.wcf.comment.commentableContent` object type whose processor implements [ICommentManager](https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/comment/manager/ICommentManager.class.php):
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-3/objectType.xml",
-    "objectType.xml"
+  title="objectType.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-3/objectType.xml"
 ) }}
 
 The `PersonCommentManager` class extended `ICommentManager`’s default implementation [AbstractCommentManager](https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/comment/manager/AbstractCommentManager.class.php):
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-3/files/lib/system/comment/manager/PersonCommentManager.class.php",
-    "files/lib/system/comment/manager/PersonCommentManager.class.php"
+  title="files/lib/system/comment/manager/PersonCommentManager.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-3/files/lib/system/comment/manager/PersonCommentManager.class.php"
 ) }}
 
 - First, the system is told the names of the permissions via the `$permission*` properties.
@@ -125,9 +125,9 @@ With this option, comments on individual people can be disabled.
 ### `PersonPage`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-3/files/lib/page/PersonPage.class.php",
-    "files/lib/page/PersonPage.class.php"
+  title="files/lib/page/PersonPage.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-3/files/lib/page/PersonPage.class.php"
 ) }}
 
 The `PersonPage` class is similar to the `PersonEditForm` in the ACP in that it reads the id of the requested person from the request data and validates the id in `readParameters()`.
@@ -138,9 +138,9 @@ The `assignVariables()` method assigns some additional template variables like `
 ### `person.tpl`
 
 {jinja{ codebox(
-    "tpl",
-    "tutorial/tutorial-series/part-3/templates/person.tpl",
-    "templates/person.tpl"
+  title="templates/person.tpl",
+  language="tpl",
+  filepath="tutorial/tutorial-series/part-3/templates/person.tpl"
 ) }}
 
 For now, the `person` template is still very empty and only shows the comments in the content area.
@@ -152,9 +152,9 @@ The attribute `wysiwygSelector` should be the id of the comment list `personComm
 ### `page.xml`
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-3/page.xml",
-    "page.xml"
+  title="page.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-3/page.xml"
 ) }}
 
 The `page.xml` file has been extended for the new person page with identifier `com.woltlab.wcf.people.Person`.
@@ -170,9 +170,9 @@ Compared to the pre-existing `com.woltlab.wcf.people.PersonList` page, there are
 ### `PersonPageHandler`
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-3/files/lib/system/page/handler/PersonPageHandler.class.php",
-    "files/lib/system/page/handler/PersonPageHandler.class.php"
+  title="files/lib/system/page/handler/PersonPageHandler.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-3/files/lib/system/page/handler/PersonPageHandler.class.php"
 ) }}
 
 Like any page handler, the `PersonPageHandler` class has to implement the [IMenuPageHandler](https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/page/handler/IMenuPageHandler.class.php) interface, which should be done by extending the [AbstractMenuPageHandler](https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/page/handler/AbstractMenuPageHandler.class.php) class.
index 232742d2c3e5c7845697f04090b1ea6caa39e6c7..94ac35f17b9122d8606481bd11fcd4cdb1789186 100644 (file)
@@ -59,9 +59,9 @@ To do so, we first have to register a new object type for this person list box c
 The `com.woltlab.wcf.boxController` object type definition requires the provided class to implement `wcf\system\box\IBoxController`:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-4/files/lib/system/box/PersonListBoxController.class.php",
-    "files/lib/system/box/PersonListBoxController.class.php"
+  title="files/lib/system/box/PersonListBoxController.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-4/files/lib/system/box/PersonListBoxController.class.php"
 ) }}
 
 By extending `AbstractDatabaseObjectListBoxController`, we only have to provide minimal data ourself and rely mostly on the default implementation provided by `AbstractDatabaseObjectListBoxController`:
@@ -100,9 +100,9 @@ We will support filtering the people by their first and last name so that, for e
 The first step for condition support is to register a object type definition for the relevant conditions requiring the `IObjectListCondition` interface:
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-4/objectTypeDefinition.xml",
-    "objectTypeDefinition.xml"
+  title="objectTypeDefinition.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-4/objectTypeDefinition.xml"
 ) }}
 
 Next, we register the specific conditions for filtering by the first and last name using this object type condition:
@@ -123,9 +123,9 @@ Next, we register the specific conditions for filtering by the first and last na
 `PersonFirstNameTextPropertyCondition` and `PersonLastNameTextPropertyCondition` only differ minimally so that we only focus on `PersonFirstNameTextPropertyCondition` here, which relies on the default implementation `AbstractObjectTextPropertyCondition` and only requires specifying different object properties:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-4/files/lib/system/condition/person/PersonFirstNameTextPropertyCondition.class.php",
-    "files/lib/system/condition/person/PersonFirstNameTextPropertyCondition.class.php"
+  title="files/lib/system/condition/person/PersonFirstNameTextPropertyCondition.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-4/files/lib/system/condition/person/PersonFirstNameTextPropertyCondition.class.php"
 ) }}
 
 1. `$className` contains the class name of the relevant database object from which the class name of the database object list is derived and `$propertyName` is the name of the database object's property that contains the value used for filtering.
index 67554cf90fb80dac11e87197ea0b6d2b150bbb51..a9fb8431d90e09b5fc683bea442714209423c028 100644 (file)
@@ -77,9 +77,9 @@ Before we focus on the main aspects of this part, we mention some minor aspects
 The PHP file with the database layout has been updated as follows:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-5/files/acp/database/install_com.woltlab.wcf.people.php",
-    "files/acp/database/install_com.woltlab.wcf.people.php"
+  title="files/acp/database/install_com.woltlab.wcf.people.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-5/files/acp/database/install_com.woltlab.wcf.people.php"
 ) }}
 
 - The number of pieces of information per person is tracked via the new `informationCount` column.
@@ -88,9 +88,9 @@ The PHP file with the database layout has been updated as follows:
   The two foreign keys ensure that if a person is deleted, all of their information is also deleted, and that if a user is deleted, the `userID` column is set to `NULL`.
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-5/files/lib/data/person/information/PersonInformation.class.php",
-    "files/lib/data/person/information/PersonInformation.class.php"
+  title="files/lib/data/person/information/PersonInformation.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-5/files/lib/data/person/information/PersonInformation.class.php"
 ) }}
 
 `PersonInformation` provides two methods, `canDelete()` and `canEdit()`, to check whether the active user can delete or edit a specific piece of information.
@@ -105,9 +105,9 @@ To generate such an output, `HtmlOutputProcessor::process()` is used and here is
 While `PersonInformationEditor` is simply the default implementation and thus not explicitly shown here, `PersonInformationList::readObjects()` caches the relevant ids of the associated people and users who created the pieces of information using runtime caches:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-5/files/lib/data/person/information/PersonInformationList.class.php",
-    "files/lib/data/person/information/PersonInformationList.class.php"
+  title="files/lib/data/person/information/PersonInformationList.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-5/files/lib/data/person/information/PersonInformationList.class.php"
 ) }}
 
 
@@ -116,9 +116,9 @@ While `PersonInformationEditor` is simply the default implementation and thus no
 The `person.tpl` template has been updated to include a block for listing the information at the beginning:
 
 {jinja{ codebox(
-    "smarty",
-    "tutorial/tutorial-series/part-5/templates/person.tpl",
-    "templates/person.tpl"
+  title="templates/person.tpl",
+  language="smarty",
+  filepath="tutorial/tutorial-series/part-5/templates/person.tpl"
 ) }}
 
 To keep things simple here, we reuse the structure and CSS classes used for comments.
@@ -142,9 +142,9 @@ To create new pieces of information or editing existing ones, we do not add new
 When clicking on the add button or on any of the edit buttons, a dialog opens with the relevant form:
 
 {jinja{ codebox(
-    "typescript",
-    "tutorial/tutorial-series/part-5/ts/WoltLabSuite/Core/Controller/Person.ts",
-    "ts/WoltLabSuite/Core/Controller/Person.ts"
+  title="ts/WoltLabSuite/Core/Controller/Person.ts",
+  language="typescript",
+  filepath="tutorial/tutorial-series/part-5/ts/WoltLabSuite/Core/Controller/Person.ts"
 ) }}
 
 We use the [`WoltLabSuite/Core/Form/Builder/Dialog` module](https://github.com/WoltLab/WCF/blob/master/ts/WoltLabSuite/Core/Form/Builder/Dialog.ts), which takes care of the internal handling with regard to these dialogs.
@@ -168,9 +168,9 @@ Explanation of the initialization arguments for `WoltLabSuite/Core/Form/Builder/
 Next, we focus on `PersonInformationAction`, which actually provides the contents of these dialogs and creates and edits the information:
 
 {jinja{ codebox(
-    "php",
-    "tutorial/tutorial-series/part-5/files/lib/data/person/information/PersonInformationAction.class.php",
-    "files/lib/data/person/information/PersonInformationAction.class.php"
+  title="files/lib/data/person/information/PersonInformationAction.class.php",
+  language="php",
+  filepath="tutorial/tutorial-series/part-5/files/lib/data/person/information/PersonInformationAction.class.php"
 ) }}
 
 When setting up the `WoltLabSuite/Core/Form/Builder/Dialog` object for adding new pieces of information, we specified `getAddDialog` and `submitAddDialog` as the names of the dialog getter and submit handler.
@@ -228,7 +228,7 @@ As we store the name of the user who create a new piece of information and store
 Lastly, we present the updated `eventListener.xml` file with new entries for all of these event listeners:
 
 {jinja{ codebox(
-    "xml",
-    "tutorial/tutorial-series/part-5/eventListener.xml",
-    "eventListener.xml"
+  title="eventListener.xml",
+  language="xml",
+  filepath="tutorial/tutorial-series/part-5/eventListener.xml"
 ) }}
\ No newline at end of file
diff --git a/main.py b/main.py
index 7867e5ac13ceb518cccf9ff87cff22869456d04a..fef165bbddc776f18960c42c82858bb9635c0f2f 100644 (file)
--- a/main.py
+++ b/main.py
@@ -1,18 +1,35 @@
 def define_env(env):
     @env.macro
-    def codebox(language, filepath, title = ""):
-        if title is not "":
-            return f"""
+    def codebox(title = None, language = "", filepath = None, contents = ""):
+        if title is not None:
+            if filepath is not None:
+                return f"""
 <div class="titledCodeBox">
     <div class="codeBoxTitle"><code>{title}</code></div>
     ```{language}
     --8<-- "{filepath}"
     ```
 </div>
+"""
+            else:
+                return f"""
+<div class="titledCodeBox">
+    <div class="codeBoxTitle"><code>{title}</code></div>
+```{language}
+{contents}
+```
+</div>
 """
         else:
-            return f"""
+            if filepath is not None:
+                return f"""
 ```{language}
 --8<-- "{filepath}"
 ```
+"""
+            else:
+                return f"""
+```{language}
+{contents}
+```
 """