diff --git a/CodeExamples/localPackages/example_extension/Classes/Controller/ExampleController.php b/CodeExamples/localPackages/example_extension/Classes/Controller/ExampleController.php new file mode 100644 index 0000000..ae243d5 --- /dev/null +++ b/CodeExamples/localPackages/example_extension/Classes/Controller/ExampleController.php @@ -0,0 +1,36 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; + +class ExampleController extends ActionController +{ + public function exampleAction() + { + // Use the code below, to output the string. + // Comment the code out, to use fluid template from + // "Resources/Private/Templates/Example/Example.html" + + return 'Hello world!'; + } +} diff --git a/CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php b/CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php new file mode 100644 index 0000000..bca38a0 --- /dev/null +++ b/CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php @@ -0,0 +1,9 @@ + 'example' + ] + ); +})(); diff --git a/Documentation/source/AddFirstPlugin.rst b/Documentation/source/AddFirstPlugin.rst index b0bde7c..b6130b4 100644 --- a/Documentation/source/AddFirstPlugin.rst +++ b/Documentation/source/AddFirstPlugin.rst @@ -1,11 +1,85 @@ Add first Plugin ================ +Let's get dirty and start with some functionality. + +Most extensions provide a *Plugin*, this is a functionality provided as content +element for TYPO3 CMS Frontend. Also *Modules* are available, that is functionality +in TYPO3 CMS Backend. + +Also many more parts like *Signals and Slots* or *Hooks* are available. You can also +provide *HashAlgorithms* some *Logger* or *CacheBackends*, etc. TYPO3 CMS can be +extended in many areas. + +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`. + Register Plugin in Backend -------------------------- -Configure Plugin for frontend +.. admonition:: Task + + Register a plugin in TYPO3 backend. + +We first need to register the Plugin in the backend. This way it will become +available as a new option for the content element *Insert Plugin*. +This is done with the following code in file +:file:`Configuration/TCA/Overrides/tt_content.php`: + +.. literalinclude:: ../../CodeExamples/localPackages/example_extension/Configuration/TCA/Overrides/tt_content.php + :language: php + +Configure Plugin for Frontend ----------------------------- +.. admonition:: Task + + Configure a plugin for TYPO3 frontend. + +To actually call some PHP Code when the content element is rendered, we need to +configure the plugin in :file:`ext_localconf.php`: + +.. literalinclude:: ../../CodeExamples/localPackages/example_extension/ext_localconf.php + :language: php + Write necessary Code -------------------- + +.. admonition:: Task + + Remove all PHP Errors, step by step. + +If we insert the plugin as content element and open the site, we should see the +following error message: + + Could not analyse class: "Workshop\\ExampleExtension\\Controller\\ExampleController" maybe not loaded or no autoloader? Class Workshop\\ExampleExtension\\Controller\\ExampleController does not exist + +This tells us that everything so far has worked as expected. TYPO3 tries to call our +*ExampleController*, which just does not exist yet. + +So let's create the controller with the following code in +:file:`Classes/Controller/ExampleController.php`: + +.. literalinclude:: ../../CodeExamples/localPackages/example_extension/Classes/Controller/ExampleController.php + :language: php + :lines: 1-27,36 + +The error message should change to: + + An action "exampleAction" does not exist in controller "Workshop\\ExampleExtension\\Controller\\ExampleController". + +Yeah, we fixed the error to get the next one. Even if our class exists, the +configured default action does not exist yet, so let's create it. + +.. literalinclude:: ../../CodeExamples/localPackages/example_extension/Classes/Controller/ExampleController.php + :language: php + :lines: 26-29,34- + +We now should see "Hello world!" in our frontend. + +We just created our first plugin. diff --git a/Documentation/source/Extension.rst b/Documentation/source/Extension.rst index 087d705..d40f9aa 100644 --- a/Documentation/source/Extension.rst +++ b/Documentation/source/Extension.rst @@ -20,7 +20,7 @@ Nowadays most installations also have a `site_` or `sitepackage` extensions, whi encapsulates the systems configuration and resources like assets and templates. Thus an TYPO3 extension is the same as an composer package. -In this workshop we will concentrate of a "typical" extension that will provide a +In this workshop we will concentrate on a "typical" extension that will provide a plugin and custom record types. This can be installed into any compatible TYPO3 installation. A new record type will be added, which can be edited in the TYPO3 backend. Also a new plugin will be added which can be added as a content element and diff --git a/Documentation/source/UnderstandTypo3Plugins.rst b/Documentation/source/UnderstandTypo3Plugins.rst new file mode 100644 index 0000000..87d6685 --- /dev/null +++ b/Documentation/source/UnderstandTypo3Plugins.rst @@ -0,0 +1,53 @@ +Understand TYPO3 Plugins +======================== + +What happened until now? + +We created an extension and a very basic plugin. + +The plugin is created with two API calls and a Controller class with a single action +method. + +What exactly are the API calls doing? And what does the PHP code in our Controller do +so far? Let's understand TYPO3! + +TYPO3 Backend +------------- + +The TYPO3 Backend needs to provide a new Plugin to the editor, this is done within +:file:`Configuration/TCA/Overrides/tt_content.php`. + +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*. + +TYPO3 Frontend rendering +------------------------ + +Also we need to configure the handling of our plugin during the rendering of TYPO3 +frontend. This is done within :file:`ext_localconf.php`. + +The API configures TypoScript ``tt_content.list.20.`` to define +rendering of the new registered ``list_type``. + +Extbase bootstrap will be started with extension and plugin name. +Also the configuration of callable controller actions and caching is stored in +``$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']``. + +The controller +-------------- + +TypoScript will call Extbase, which will figure out to call the ``exampleAction`` +method of our ``ExampleController``, thanks to our frontend rendering configuration. + +The default action is always the first action of the first controller in the +configuration. Multiple actions will be shown later. + +The Controller should extend the ``ActionController`` to work as expected out of the +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``. diff --git a/Documentation/source/Views.rst b/Documentation/source/Views.rst index decdeed..66bcf54 100644 --- a/Documentation/source/Views.rst +++ b/Documentation/source/Views.rst @@ -1,4 +1,63 @@ Views ===== +So far we only have our "Hello world!" output hardcoded in our PHP Code. +That's not helpful, so let's introduce Views with Fluid. +Fluid +----- + +Fluid is the TYPO3 Template engine. Nowadays it's standalone, but was developed for +and by TYPO3. + +It follows XML / HTML which should make it easier to get started. + +Fluid templates are valid HTML and custom tags, called ViewHelpers, are introduced to +bring in logic. + +Convention over configuration +----------------------------- + +Extbase follows the principle "Convention over configuration", which we already saw +with our Controller. We didn't configure the path or class name, it just follows a +convention. + +Same is true for the output of plugins. If "something" is returned, this will be the +output. If nothing is returned, Extbase will call Fluid to render a Fluid template. + +Paths +----- + +The path to the template of an controller action is +:file:`example_extension/Resources/Private/Templates/ControllerName/ActionName.html`, +which in our example would be: :file:`example_extension/Resources/Private/Templates/Example/Example.html`, + +.. admonition:: Task + + Move the output to a fluid template, following Extbase conventions. + +So let's create the file and move the "Hello world!" to this file. We should make a +small change, otherwise we will not see whether our change has worked. E.g. make the +"w" uppercase "W". + +Do not forget to remote the ``return 'Hello world!';`` from our controller. + +We should now see our "Hello World!". + +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. + +But they should be able to change template ins their own extension, e.g. a +"sitepackage". Let's take a look how this works. + +Further resources +----------------- + +* https://github.com/TYPO3/Fluid + +* https://docs.typo3.org/typo3cms/TyposcriptReference/ContentObjects/Fluidtemplate/Index.html + +* https://docs.typo3.org/typo3cms/ExtbaseFluidBook/Index.html diff --git a/Documentation/source/conf.py b/Documentation/source/conf.py index f1dff4d..df0fb2c 100644 --- a/Documentation/source/conf.py +++ b/Documentation/source/conf.py @@ -309,3 +309,10 @@ texinfo_documents = [ intersphinx_mapping = { 't3coreapi': ('https://docs.typo3.org/typo3cms/CoreApiReference/', None), } + +# Allow inline PHP highlighting +# See: https://github.com/guzzle/guzzle/blob/master/docs/conf.py + +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer +lexers['php'] = PhpLexer(startinline=True, linenos=1) diff --git a/Documentation/source/index.rst b/Documentation/source/index.rst index 0357706..5d91878 100644 --- a/Documentation/source/index.rst +++ b/Documentation/source/index.rst @@ -3,8 +3,29 @@ Welcome to TYPO3 Extension Workshop This workshop is about the basics of TYPO3 extensions. +Some "rules" for the workshop +----------------------------- + +* You will write all the code yourself. The repository is available though, if you need + help or are to lazy… . + +* 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 + work from 4.5 onwards. + +* Ask questions as soon as possible. This way we have the context. + +* All materials are available on Github: https://github.com/DanielSiepmann/typo3-extension-workshop + +* When should we make breaks? Any Smokers here? + +Topics +------ + We will cover the following topics during the workshop, to build a foundation to -build custom extensions. +build custom extensions: .. toctree:: :maxdepth: 2 @@ -13,6 +34,7 @@ build custom extensions. Extension StartNewExtension AddFirstPlugin + UnderstandTypo3Plugins Views Configuration CustomRecords