Compare commits

...

10 commits

Author SHA1 Message Date
Daniel Siepmann 6c82803538
TASK: Add link for symfony commands 2019-03-01 10:50:09 +01:00
Daniel Siepmann 27fc9bcb41
TASK: Update TYPO3 2019-03-01 10:38:00 +01:00
Daniel Siepmann 58030d7b69
TASK: Remove example plugin
* In order to not waste time.
* In order to not irritate participants with two plugins.
2019-03-01 10:32:32 +01:00
Daniel Siepmann a99c42257c Merge branch 'develop' into 'master'
State after Workshop at TYPO3 Camp Rhein Ruhr 2018

See merge request internal/events/trainings/typo3-extension-workshop!1
2018-11-05 09:37:54 +01:00
Daniel Siepmann 0c41f688cf
TASK: Add output of flash messages to docs 2018-11-05 09:37:10 +01:00
Daniel Siepmann 6223616d15
TASK: Add missing path to TCA file 2018-11-05 09:29:52 +01:00
Daniel Siepmann 7ca9b4a7d3
TASK: Add info about how to show helpful error messages 2018-11-05 09:23:04 +01:00
Daniel Siepmann ca8197a4de
TASK: Update docs pre workshop 2018-11-05 09:20:34 +01:00
Daniel Siepmann fd69c91652
TASK: Add translated flash message after record was edited 2018-11-05 09:19:45 +01:00
Daniel Siepmann 8c13a05cb4
TASK: Update TYPO3 to 9.5.1 2018-11-05 09:19:19 +01:00
21 changed files with 336 additions and 377 deletions

View file

@ -37,10 +37,6 @@
"app-dir": "app",
"root-dir": "app",
"web-dir": "public"
},
"helhum/typo3-console": {
"comment": "This option is not needed any more for helhum/typo3-console 5.x",
"install-extension-dummy": false
}
},
"minimum-stability": "dev",

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@ namespace Workshop\ExampleExtension\Controller;
*/
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use Workshop\ExampleExtension\Domain\Model\Address;
use Workshop\ExampleExtension\Domain\Repository\AddressRepository;
@ -55,7 +56,10 @@ class AddressController extends ActionController
$this->addressRepository->update($address);
$this->addFlashMessage(
$address->getCompanyName() . ' was updated.',
LocalizationUtility::translate('flashSuccess', 'ExampleExtension', [
'companyName' => $address->getCompanyName(),
'street' => $address->getStreet(),
]),
'Update successfully'
);
$this->redirect('index');

View file

@ -1,36 +0,0 @@
<?php
namespace Workshop\ExampleExtension\Controller;
/*
* Copyright (C) 2018 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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!';
}
}

View file

@ -1,12 +1,6 @@
<?php
(function () {
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Workshop.ExampleExtension',
'pluginkey',
'Example Plugin'
);
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Workshop.ExampleExtension',
'Address',

View file

@ -30,6 +30,10 @@
<trans-unit id="error.address.zip.1221565130" xml:space="preserve">
<source>Please provide a valid ZIP consisting of 5 digits.</source>
</trans-unit>
<trans-unit id="flashSuccess" xml:space="preserve">
<source>Update des Datensatzes %1$s war Erfolgreich.</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -1,3 +1,4 @@
<f:flashMessages />
<f:for each="{addresses}" as="address">
<h3>{address.companyName}</h3>
<address>

View file

@ -1,14 +1,6 @@
<?php
(function () {
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Workshop.ExampleExtension',
'pluginkey',
[
'Example' => 'example'
]
);
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Workshop.ExampleExtension',
'Address',
@ -27,13 +19,13 @@
wizardItems {
plugins {
elements {
exampleElement {
iconIdentifier = content-coffee
title = Example title
description = Example Description
address {
iconIdentifier = content-marker
title = Addresses
description = Allows to List and edit addresses
tt_content_defValues {
CType = list
list_type = exampleextension_pluginkey
list_type = exampleextension_address
}
}
}

View file

@ -1,3 +1,5 @@
.. _add-first-plugin:
Add first Plugin
================
@ -16,7 +18,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 display a hardcoded string.
As mentioned, we will start with a simple example plugin to display "Hello World".
Register Plugin in Backend
--------------------------
@ -35,8 +37,8 @@ This is done with the following code in file
(function () {
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Workshop.ExampleExtension',
'pluginkey',
'Example Plugin'
'Address',
'Address Plugin'
);
})();
@ -55,9 +57,9 @@ configure the plugin in :file:`ext_localconf.php`:
(function () {
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Workshop.ExampleExtension',
'pluginkey',
'Address',
[
'Example' => 'example'
'Address' => 'index'
]
);
})();
@ -70,31 +72,48 @@ Write necessary Code
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:
If we insert the plugin as content element and open the site, we should see an error
message. This message is not helpful, so we will switch to development context within
the installation / maintenance tool. Also we will add the following TypoScript setup
for our local development instance:
Could not analyse class: "Workshop\\ExampleExtension\\Controller\\ExampleController" maybe not loaded or no autoloader? Class Workshop\\ExampleExtension\\Controller\\ExampleController does not exist
.. code-block:: typoscript
config.contentObjectExceptionHandler = 0
Afterwards we should see the following error message:
Could not analyse class: "Workshop\\ExampleExtension\\Controller\\AddressController" maybe not loaded or no autoloader? Class Workshop\\ExampleExtension\\Controller\\AddressController 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.
*AddressController*, which just does not exist yet.
So let's create the controller with the following code in
:file:`Classes/Controller/ExampleController.php`:
:file:`Classes/Controller/AddressController.php`:
.. literalinclude:: ../../CodeExamples/localPackages/example_extension/Classes/Controller/ExampleController.php
:language: php
:lines: 1-27,36
.. code-block:: php
namespace Workshop\ExampleExtension\Controller;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class AddressController extends ActionController
{
}
The error message should change to:
An action "exampleAction" does not exist in controller "Workshop\\ExampleExtension\\Controller\\ExampleController".
An action "indexAction" does not exist in controller "Workshop\\ExampleExtension\\Controller\\AddressController".
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-
.. code-block:: php
public function indexAction()
{
return 'Hello world!';
}
We now should see "Hello world!" in our frontend.

View file

@ -70,7 +70,7 @@ The configuration via TypoScript has to be located at a specific path:
// For a specific frontend plugin of the extension
plugin {
tx_exampleextension_pluginkey {
tx_exampleextension_addresspluginkey {
settings {
// The configuration goes here
}
@ -95,7 +95,7 @@ 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::
E.g. introduce a new namespace ``codappix`` with project specific settings::
plugin {
tx_exampleextension {
@ -203,6 +203,8 @@ we can pre select the plugin.
See: https://docs.typo3.org/typo3cms/TSconfigReference/PageTsconfig/Mod.html#wizards
Available TYPO3 Icons can be found here: https://typo3.github.io/TYPO3.Icons/
.. _configuration-view-paths:
Adjusting view paths

View file

@ -17,7 +17,7 @@ TCA
Before we can do anything with Extbase, we need to configure TYPO3. The TCA (=Table
Configuration Array) contains configuration for each database table. TYPO3 will
generate the list view and edit forms from this configuration.
generate the list view and edit forms within the Backend from this configuration.
Extbase uses this configuration for mapping and database queries, together with
relation handling.
@ -30,7 +30,10 @@ One thing to notice is that Extbase uses "Convention over Configuration". While
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
table would be ``tx_exampleextension_domain_model_address``. So this will be
our database table name for our example.
our database table name for our example. Also TYPO3 uses convention over
configuration, so the TCA for this table is placed within
:file:`Configuration/TCA/tx_exampleextension_domain_model_address.php` within our
Extension.
Also each property within the model is written lowerCamelCase, while the database
columns are written snake_case.
@ -49,6 +52,9 @@ Our new record will be an address record with the following fields:
* Country
Once we finished the TCA, we already can create new records. Only saving them does
not work, as we didn't setup the database yet.
.. note::
By default new records are only allowed on pages of type "Folder".
@ -75,6 +81,7 @@ The example :file:`ext_tables.sql` is:
.. literalinclude:: ../../CodeExamples/localPackages/example_extension/ext_tables.sql
:language: sql
:linenos:
All further TYPO3 specific fields, like ``uid`` and ``pid`` are added by TYPO3 CMS since v9.
@ -106,6 +113,9 @@ Before v9, the file would look like:
KEY parent (pid)
);
We should now be able to create and save new records within the TYPO3 backend. Also
existing records should be listed, searchable and editable.
Model
-----
@ -119,7 +129,7 @@ our case this has to match the table name and is called
``Workshop\ExampleExtension\Domain\Model\Address`` and located at
:file:`Classes/Domain/Model/Address.php`.
Each model is a PHP class structure like:
Each model is a PHP class, structured like:
.. literalinclude:: ../../CodeExamples/localPackages/example_extension/Classes/Domain/Model/Address.php
:language: php
@ -189,7 +199,7 @@ With our records in our template, we can iterate over them to display them.
.. literalinclude:: ../../CodeExamples/localPackages/example_extension/Resources/Private/Templates/Address/Index.html
:language: html
:linenos:
:lines: 1-7,10
:lines: 2-8,11
Configure storage pid
---------------------
@ -213,3 +223,16 @@ We could also configure the pid via TypoScript:
}
}
Check everything
----------------
Once everything is set up, the following should be possible:
* Create, edit, search and delete records within TYPO3 Backend.
* List available records via Frontend Plugin.
Sounds like a lot of work for a small benefit? Right. If all you have to achieve is
this, you should not use Extbase but "pure" TYPO3. But we will extend the Extension
in the next step. Also this is about a first simple Extbase Extension, not how to use
TYPO3 the right way.

View file

@ -12,11 +12,11 @@ TYPO3 is built only with extensions, there is no framework below. All features a
assigned to a specific extension. This way it's possible to build the TYPO3 that fits
the project needs.
An extension is something like `frontend` or `backend`, which provides the TYPO3
frontend or backend. It can also be `extbase` or `fluid` which provides and Framework
to build further extensions or an template engine.
An extension is something like ``frontend`` or ``backend``, which provides the TYPO3
frontend or backend. It can also be ``extbase`` which works as an Framework
to build further extensions or ``fluid`` an template engine.
Nowadays most installations also have a `site_` or `sitepackage` extensions, which
Nowadays most installations also have a ``site_`` or ``sitepackage`` extensions, which
encapsulates the systems configuration and resources like assets and templates. Thus
an TYPO3 extension is the same as an composer package.

View file

@ -11,9 +11,7 @@ If we have some time left, we can take a deeper look at some of these topics.
Outlook/Dependency-Injection
Outlook/Automated-Testing
Outlook/Property-Mapper
Outlook/Coding-Guideline
Outlook/Command-Controllers
Outlook/Backend-Modules
Outlook/Fluid/Custom-ViewHelper
Outlook/Fluid/Concepts-of-Models
Outlook/Configuration/Mapping-DB

View file

@ -1,2 +0,0 @@
Coding Guideline
================

View file

@ -3,4 +3,6 @@ Command Controllers
See:
* https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/BackendModules/CliScripts/Index.html
* https://docs.typo3.org/typo3cms/ExtbaseFluidBook/10-Outlook/3-Command-controllers.html

View file

@ -1,2 +0,0 @@
Fluid - Concepts of Models
==========================

View file

@ -1,12 +1,16 @@
Start new extension
===================
We will start with the simplest example ``Hello World``. Once we understood the
basics, we will create an "address" extension to manage a custom record.
Necessary files
---------------
The only necessary file is :file:`ext_emconf.php`. This configures the *Extension
Manager*. Without this file, the Extension Manager would not recognize the extension
and would prevent installation.
Extensions consists of a folder and the single necessary file, which is
:file:`ext_emconf.php`. This configures the *Extension Manager*. Without this file,
the Extension Manager would not recognize the extension and would prevent
installation.
.. literalinclude:: ../../CodeExamples/localPackages/example_extension/ext_emconf.php
:language: php
@ -15,7 +19,9 @@ See :ref:`t3coreapi:extension-declaration` in TYPO3 Core API Reference.
.. admonition:: Task
So let's create a new folder and add the file.
So let's create a new folder and add the file within the folder.
In this example I'll use :file:`example_extension` as folder name.
Install extension
-----------------

View file

@ -39,8 +39,8 @@ Also the configuration of callable controller actions and caching is stored in
The controller
--------------
TypoScript will call Extbase, which will figure out to call the ``exampleAction``
method of our ``ExampleController``, thanks to our frontend rendering configuration.
TypoScript will call Extbase, which will figure out to call the ``indexAction``
method of our ``AddressController``, 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.

View file

@ -37,7 +37,7 @@ edit a record, you could use the following:
:language: html
:linenos:
:dedent: 4
:lines: 9
:lines: 10
The ViewHelper generates a link, thanks to the current plugin context, all arguments
are prefixed with the plugin namespace.
@ -165,6 +165,13 @@ This is also just one line within a controller::
'Update successfully'
);
Adding alone would not work, so we have to display thus messages. This is done within
the View with an ViewHelper:
.. code-block:: html
<f:flashMessages />
Validation
----------

View file

@ -32,7 +32,7 @@ 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`,
which in our example would be: :file:`example_extension/Resources/Private/Templates/Address/Index.html`,
.. admonition:: Task

View file

@ -1,7 +1,7 @@
Welcome to TYPO3 Extension Workshop
===================================
This workshop is about the basics of TYPO3 extensions.
This workshop is about the basics of TYPO3 extensions, using Extbase and Fluid.
Some "rules" for the workshop
-----------------------------
@ -17,6 +17,8 @@ Some "rules" for the workshop
* Ask questions as soon as possible. This way we have the context.
* Tell me if you want less details.
* All materials are available on Github: https://github.com/DanielSiepmann/typo3-extension-workshop
* When should we make breaks? Any Smokers here?