Compare commits
10 commits
08acce4619
...
6c82803538
Author | SHA1 | Date | |
---|---|---|---|
Daniel Siepmann | 6c82803538 | ||
Daniel Siepmann | 27fc9bcb41 | ||
Daniel Siepmann | 58030d7b69 | ||
a99c42257c | |||
Daniel Siepmann | 0c41f688cf | ||
Daniel Siepmann | 6223616d15 | ||
Daniel Siepmann | 7ca9b4a7d3 | ||
Daniel Siepmann | ca8197a4de | ||
Daniel Siepmann | fd69c91652 | ||
Daniel Siepmann | 8c13a05cb4 |
|
@ -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",
|
||||
|
|
499
CodeExamples/composer.lock
generated
499
CodeExamples/composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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');
|
||||
|
|
|
@ -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!';
|
||||
}
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<f:flashMessages />
|
||||
<f:for each="{addresses}" as="address">
|
||||
<h3>{address.companyName}</h3>
|
||||
<address>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Coding Guideline
|
||||
================
|
|
@ -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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Fluid - Concepts of Models
|
||||
==========================
|
|
@ -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
|
||||
-----------------
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
----------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
Loading…
Reference in a new issue