diff --git a/CodeExamples/composer.lock b/CodeExamples/composer.lock index 9aa6adb..3ee5f10 100644 --- a/CodeExamples/composer.lock +++ b/CodeExamples/composer.lock @@ -3977,10 +3977,11 @@ "dist": { "type": "path", "url": "localPackages/example_extension", - "reference": "041dbef29fa3c6cecf8bb21f203da0ea7cf11cb8", + "reference": "9c0990fe6a3271225e01dc16e429eaeee8cb0037", "shasum": null }, "require": { + "php": ">=7.2.0", "typo3/cms-core": "*" }, "type": "typo3-cms-extension", diff --git a/CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php b/CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php index 529b61a..bb31ddc 100644 --- a/CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php +++ b/CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php @@ -6,6 +6,7 @@ 'pluginkey', 'Example Plugin' ); + \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'Workshop.ExampleExtension', 'Address', diff --git a/CodeExamples/localPackages/example_extension/composer.json b/CodeExamples/localPackages/example_extension/composer.json index ec190e1..5b09e62 100644 --- a/CodeExamples/localPackages/example_extension/composer.json +++ b/CodeExamples/localPackages/example_extension/composer.json @@ -15,6 +15,7 @@ } }, "require": { + "php": ">=7.2.0", "typo3/cms-core": "*" } } diff --git a/CodeExamples/localPackages/example_extension/ext_emconf.php b/CodeExamples/localPackages/example_extension/ext_emconf.php index 7602002..f9b7c2c 100644 --- a/CodeExamples/localPackages/example_extension/ext_emconf.php +++ b/CodeExamples/localPackages/example_extension/ext_emconf.php @@ -11,8 +11,8 @@ $EM_CONF['example_extension'] = [ 'author_company' => 'Codappix', 'constraints' => [ 'depends' => [ - 'typo3' => '8.7.0-8.7.999', - 'php' => '7.0.0-7.2.999', + 'php' => '7.2.0-7.2.999', + 'typo3' => '8.7.0-9.5.999', ], ], 'autoload' => [ diff --git a/CodeExamples/localPackages/example_extension/ext_localconf.php b/CodeExamples/localPackages/example_extension/ext_localconf.php index cd5656e..a2f8373 100644 --- a/CodeExamples/localPackages/example_extension/ext_localconf.php +++ b/CodeExamples/localPackages/example_extension/ext_localconf.php @@ -19,4 +19,28 @@ 'Address' => 'update' ] ); + + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(' + mod { + wizards { + newContentElement { + wizardItems { + plugins { + elements { + exampleElement { + iconIdentifier = content-coffee + title = Example title + description = Example Description + tt_content_defValues { + CType = list + list_type = exampleextension_pluginkey + } + } + } + } + } + } + } + } + '); })(); diff --git a/CodeExamples/localPackages/example_extension/ext_tables.sql b/CodeExamples/localPackages/example_extension/ext_tables.sql index d340b20..464c5ff 100644 --- a/CodeExamples/localPackages/example_extension/ext_tables.sql +++ b/CodeExamples/localPackages/example_extension/ext_tables.sql @@ -1,22 +1,8 @@ CREATE TABLE tx_exampleextension_domain_model_address ( - uid int(11) unsigned NOT NULL auto_increment, - pid int(11) unsigned DEFAULT '0' NOT NULL, - - crdate int(11) unsigned DEFAULT '0' NOT NULL, - cruser_id int(11) unsigned DEFAULT '0' NOT NULL, - tstamp int(11) unsigned DEFAULT '0' NOT NULL, - hidden tinyint(3) unsigned DEFAULT '0' NOT NULL, - deleted tinyint(3) unsigned DEFAULT '0' NOT NULL, - starttime int(11) unsigned DEFAULT '0' NOT NULL, - endtime int(11) unsigned DEFAULT '0' NOT NULL, - company_name varchar(255) DEFAULT '' NOT NULL, street varchar(255) DEFAULT '' NOT NULL, house_number varchar(255) DEFAULT '' NOT NULL, zip varchar(255) DEFAULT '' NOT NULL, city varchar(255) DEFAULT '' NOT NULL, country varchar(255) DEFAULT '' NOT NULL, - - PRIMARY KEY (uid), - KEY parent (pid) ); diff --git a/Documentation/source/AddFirstPlugin.rst b/Documentation/source/AddFirstPlugin.rst index 9cf8c87..280f41d 100644 --- a/Documentation/source/AddFirstPlugin.rst +++ b/Documentation/source/AddFirstPlugin.rst @@ -16,8 +16,7 @@ Still Plugins are a very typical thing to bring in features to your website. The Plugin ---------- -We will start with a very basic plugin that will only list some TYPO3 records, e.g. -`fe_users`. +We will start with a very basic plugin that will display a hardcoded string. Register Plugin in Backend -------------------------- diff --git a/Documentation/source/Configuration.rst b/Documentation/source/Configuration.rst index 0ca9121..aec127b 100644 --- a/Documentation/source/Configuration.rst +++ b/Documentation/source/Configuration.rst @@ -1,3 +1,5 @@ +.. _configuration: + Configuration ============= @@ -45,12 +47,12 @@ TypoScript TypoScript and Flexforms are merged by Extbase, so you do not have to do any additional work and combine both. They are available as Variable ``{settings}`` in -all Templates. Also inside the Controller they are available as array in +all templates. Also inside the Controller they are available as array in ``$this->settings`` out of the box. .. admonition:: Task - Add some settings and print them in Template and Controller. + Add some settings and print them in template and controller. The configuration via TypoScript has to be located at a specific path: @@ -93,6 +95,20 @@ book. The whole ``settings`` array is passed into all templates, layouts and partials. This way it's possible for integrators to provide arbitary information. + E.g. introduce a new namespace:: + + plugin { + tx_exampleextension { + settings { + codappix { + pageUids { + detail = {$pageUids.exampleextension.detail} + } + } + } + } + } + Also it's possible to insert a plugin via TypoScript. In that case the settings can be provided only for that instance: @@ -113,9 +129,10 @@ be provided only for that instance: Flexforms ^^^^^^^^^ -Flexforms are like TCA, which will be covered later on. The format is XML instead of -PHP and saved inside the database field ``pi_flexform`` of the ``tt_content`` record. -This way editors are able to adjust provided settings within a plugin record. +Flexforms are like TCA, which will be covered at :ref:`custom-records-tca` section of +:ref:`custom-records`. The format is XML instead of PHP and saved inside the database +field ``pi_flexform`` of the ``tt_content`` record. This way editors are able to +adjust provided settings within a plugin record. Custom ^^^^^^ @@ -127,7 +144,7 @@ When to use which ----------------- The Flexform approach provides the best UX as it uses the known UI of TYPO3 inside a -record. +record. It should be used if the setting is plugin instance related. The TypoScript provided the best UX when integrators have to deploy configuration or configuration is necessary on multiple pages. Also if the plugin is inserted directly @@ -136,3 +153,77 @@ via TypoScript. The PHP approach is best suited for instance wide configuration, which nearly never exists. Things like API Keys might depend on the current Domain or Website, and there can be multiple in a single TYPO3 instance. + +.. _configuration-content-wizard: + +Adding Content Wizard for our Plugin +------------------------------------ + +So far we do not have any configuration. But we can use PageTSConfig to make live +easier for editors. + +Right now an editor has to insert a new "Insert Plugin" content record and choose our +plugin. We can provide a Configuration to make our Plugin available via the "Create +new content element" wizard. + +.. admonition:: Task + + Add the new Plugin to content element wizard. + +Within :file:`ext_localconf.php` we add the following:: + + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(' + mod { + wizards { + newContentElement { + wizardItems { + plugins { + elements { + exampleElement { + iconIdentifier = content-coffee + title = Example title + description = Example Description + tt_content_defValues { + CType = list + list_type = exampleextension_pluginkey + } + } + } + } + } + } + } + } + '); + +This will add the given PageTS as default to global configuration. Within the TS we +define a new element ``exampleElement`` with icon, title and description. The important +part is, that we can define default values (``defValues``) for the creation. This way +we can pre select the plugin. + +See: https://docs.typo3.org/typo3cms/TSconfigReference/PageTsconfig/Mod.html#wizards + +.. _configuration-view-paths: + +Adjusting view paths +-------------------- + +In :ref:`views` we covered the conventions for paths. However sometimes you need to +change these paths. E.g. if you exchange a Partial or template. + +This can be done via TypoScript, the same way as for ``FLUIDTEMPLATE`` cObject: + +.. code-block:: typoscript + :linenos: + + plugin { + tx_exampleextension { + view { + templateRootPaths { + 10 = EXT:sitepackage/Resources/Plugins/ExampleExtension/Templates/ + } + } + } + } + +See: https://docs.typo3.org/typo3cms/TyposcriptReference/ContentObjects/Fluidtemplate/Index.html diff --git a/Documentation/source/CustomRecords.rst b/Documentation/source/CustomRecords.rst index 061aa31..88534bc 100644 --- a/Documentation/source/CustomRecords.rst +++ b/Documentation/source/CustomRecords.rst @@ -1,9 +1,13 @@ +.. _custom-records: + Custom records ============== The basics are behind us, now let's get deeper into the system and create a new record type, like ``tt_address`` which can be displayed through our plugin. +.. _custom-records-tca: + TCA --- @@ -24,7 +28,7 @@ information are available there. One thing to notice is that Extbase uses "Convention over Configuration". While we can configure Extbase to map a Model to a specific database table, we can auto match -them. For a Model ``Workshop\ExampleExtension\Domain\Model\Address``, the database +them. For a Model ``\Workshop\ExampleExtension\Domain\Model\Address``, the database table would be ``tx_exampleextension_domain_model_address``. So this will be our database table name for our example. @@ -62,7 +66,7 @@ ext_tables.sql Once the TCA is provided, we need to create the table in our Database. Each extension can provide a :file:`ext_tables.sql` in the root directory. Within the -install tool and TYPO3 Console, you can update the database schema to match the +admin tools and TYPO3 Console, you can update the database schema to match the current necessary structure of all extensions. If multiple extensions adjust the same field, the last one in load order is used. @@ -72,6 +76,37 @@ The example :file:`ext_tables.sql` is: .. literalinclude:: ../../CodeExamples/localPackages/example_extension/ext_tables.sql :language: sql +All further TYPO3 specific fields, like ``uid`` and ``pid`` are added by TYPO3 CMS since v9. + +Before v9, the file would look like: + +.. code-block:: sql + :linenos: + + CREATE TABLE tx_exampleextension_domain_model_address ( + uid int(11) unsigned NOT NULL auto_increment, + pid int(11) unsigned DEFAULT '0' NOT NULL, + + crdate int(11) unsigned DEFAULT '0' NOT NULL, + cruser_id int(11) unsigned DEFAULT '0' NOT NULL, + tstamp int(11) unsigned DEFAULT '0' NOT NULL, + hidden tinyint(3) unsigned DEFAULT '0' NOT NULL, + deleted tinyint(3) unsigned DEFAULT '0' NOT NULL, + starttime int(11) unsigned DEFAULT '0' NOT NULL, + endtime int(11) unsigned DEFAULT '0' NOT NULL, + + company_name varchar(255) DEFAULT '' NOT NULL, + street varchar(255) DEFAULT '' NOT NULL, + house_number varchar(255) DEFAULT '' NOT NULL, + zip varchar(255) DEFAULT '' NOT NULL, + city varchar(255) DEFAULT '' NOT NULL, + country varchar(255) DEFAULT '' NOT NULL, + + PRIMARY KEY (uid), + KEY parent (pid) + ); + + Model ----- diff --git a/Documentation/source/StartNewExtension.rst b/Documentation/source/StartNewExtension.rst index accaa66..83a85bc 100644 --- a/Documentation/source/StartNewExtension.rst +++ b/Documentation/source/StartNewExtension.rst @@ -31,10 +31,6 @@ or via composer. Oldschool ^^^^^^^^^ -.. todo:: - - Add note about autoloading. - Copy the extension to :file:`typo3conf/ext/`, and head over to *Extension Manager* to activate the extension. diff --git a/Documentation/source/UnderstandTypo3Plugins.rst b/Documentation/source/UnderstandTypo3Plugins.rst index 87d6685..53ad56c 100644 --- a/Documentation/source/UnderstandTypo3Plugins.rst +++ b/Documentation/source/UnderstandTypo3Plugins.rst @@ -20,7 +20,8 @@ The TYPO3 Backend needs to provide a new Plugin to the editor, this is done with The API configures the TCA (=Table Configuration Array) for ``tt_content``. And adds the new plugin as ``list_type``. -We can go further on the content element during the Topic *Configuration*. +We can go further on the content element during the Topic :ref:`configuration`, +especially :ref:`configuration-content-wizard`. TYPO3 Frontend rendering ------------------------ @@ -50,4 +51,4 @@ box. Also all "actions" must have the suffix ``Action`` and need to be public. As soon as an action returns a string, this will be the output. If nothing is returned, which is ``null`` Extbase will try to find and render a template matching our current controller and action. This is done at -``TYPO3\CMS\Extbase\Mvc\Controller\ActionController::callActionMethod``. +``\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::callActionMethod``. diff --git a/Documentation/source/Views.rst b/Documentation/source/Views.rst index 3e14063..0d4f9d5 100644 --- a/Documentation/source/Views.rst +++ b/Documentation/source/Views.rst @@ -1,3 +1,5 @@ +.. _views: + Views ===== @@ -48,16 +50,17 @@ Configuration ------------- Awesome, we now do no longer need to touch PHP code to change the output, we can use -Fluid and an Integrator or Frontendler is able to change something. +Fluid and an Integrator is able to change something. But they should be able to change templates in their own extension, e.g. a -"sitepackage". We will see how to do this in next chapter "Configuration". +"sitepackage". We will see how to do this in next chapter :ref:`configuration`, +especially :ref:`configuration-view-paths`. Sections -------- If templates grow in size, we need to add some structure. One way is to use sections -inside a single Template. A section is like a PHP method or function and can be +inside a single template. A section is like a PHP method or function and can be called with arguments: .. code-block:: html @@ -114,12 +117,12 @@ Assigned variables can be accessed inside Fluid with curly braces: ViewHelper ---------- -To make Templates more flexible, ViewHelpers are available. They are custom HTML-Tags -available inside via template engine. +To make templates more flexible, ViewHelpers are available. They are custom HTML-Tags +available inside the template engine. TYPO3 and Fluid already ship some ViewHelpers, but you can provide own ViewHelpers. -ViewHelpers always live in a Namespace, e.g. ``TYPO3\CMS\Fluid\ViewHelpers`` or -``Workshop\\ExampleExtension\\ViewHelpers``. +ViewHelpers always live in a Namespace, e.g. ``\TYPO3\CMS\Fluid\ViewHelpers`` or +``\Workshop\ExampleExtension\ViewHelpers``. You can either register these namespaces globally, or inside the templates via ``{namespace wee=Workshop\ExampleExtension\ViewHelpers}``. @@ -144,17 +147,17 @@ notation": .. code-block:: html :linenos: - {f:format.date(date: 'now')} + {f:format.date(date: 'midnight')} It's also possible to chain ViewHelpers in both ways: .. code-block:: html :linenos: - {f:format.date(date: 'now') -> f:format.raw()} + {f:format.date(date: 'midnight') -> f:format.raw()} - {f:format.date(date: 'now')} + {f:format.date(date: 'midnight')} @@ -171,7 +174,7 @@ Partials and Layouts We already saw sections to make a single template easier to manage. For re-using parts between multiple templates there are Partials. -Partials are like Templates and can be rendered via: +Partials are like templates and can be rendered via: .. code-block:: html :linenos: diff --git a/Documentation/source/index.rst b/Documentation/source/index.rst index 031504c..86abafa 100644 --- a/Documentation/source/index.rst +++ b/Documentation/source/index.rst @@ -12,7 +12,7 @@ Some "rules" for the workshop * We will not call APIs without checking out their code. Always understand what your own code does. -* I'm using the latest TYPO3 CMS 8 LTS, most of the parts are so basic, they should +* I'm using the latest TYPO3 CMS 9 LTS, most of the parts are so basic, they should work from 4.5 onwards. * Ask questions as soon as possible. This way we have the context.