TASK: Update some CMS 9 stuff and review
This commit is contained in:
parent
3701a4e492
commit
2094df147a
13 changed files with 183 additions and 45 deletions
3
CodeExamples/composer.lock
generated
3
CodeExamples/composer.lock
generated
|
@ -3977,10 +3977,11 @@
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "path",
|
"type": "path",
|
||||||
"url": "localPackages/example_extension",
|
"url": "localPackages/example_extension",
|
||||||
"reference": "041dbef29fa3c6cecf8bb21f203da0ea7cf11cb8",
|
"reference": "9c0990fe6a3271225e01dc16e429eaeee8cb0037",
|
||||||
"shasum": null
|
"shasum": null
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"php": ">=7.2.0",
|
||||||
"typo3/cms-core": "*"
|
"typo3/cms-core": "*"
|
||||||
},
|
},
|
||||||
"type": "typo3-cms-extension",
|
"type": "typo3-cms-extension",
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
'pluginkey',
|
'pluginkey',
|
||||||
'Example Plugin'
|
'Example Plugin'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'Workshop.ExampleExtension',
|
'Workshop.ExampleExtension',
|
||||||
'Address',
|
'Address',
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"php": ">=7.2.0",
|
||||||
"typo3/cms-core": "*"
|
"typo3/cms-core": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ $EM_CONF['example_extension'] = [
|
||||||
'author_company' => 'Codappix',
|
'author_company' => 'Codappix',
|
||||||
'constraints' => [
|
'constraints' => [
|
||||||
'depends' => [
|
'depends' => [
|
||||||
'typo3' => '8.7.0-8.7.999',
|
'php' => '7.2.0-7.2.999',
|
||||||
'php' => '7.0.0-7.2.999',
|
'typo3' => '8.7.0-9.5.999',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'autoload' => [
|
'autoload' => [
|
||||||
|
|
|
@ -19,4 +19,28 @@
|
||||||
'Address' => 'update'
|
'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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
');
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,22 +1,8 @@
|
||||||
CREATE TABLE tx_exampleextension_domain_model_address (
|
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,
|
company_name varchar(255) DEFAULT '' NOT NULL,
|
||||||
street varchar(255) DEFAULT '' NOT NULL,
|
street varchar(255) DEFAULT '' NOT NULL,
|
||||||
house_number varchar(255) DEFAULT '' NOT NULL,
|
house_number varchar(255) DEFAULT '' NOT NULL,
|
||||||
zip varchar(255) DEFAULT '' NOT NULL,
|
zip varchar(255) DEFAULT '' NOT NULL,
|
||||||
city varchar(255) DEFAULT '' NOT NULL,
|
city varchar(255) DEFAULT '' NOT NULL,
|
||||||
country varchar(255) DEFAULT '' NOT NULL,
|
country varchar(255) DEFAULT '' NOT NULL,
|
||||||
|
|
||||||
PRIMARY KEY (uid),
|
|
||||||
KEY parent (pid)
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,8 +16,7 @@ Still Plugins are a very typical thing to bring in features to your website.
|
||||||
The Plugin
|
The Plugin
|
||||||
----------
|
----------
|
||||||
|
|
||||||
We will start with a very basic plugin that will only list some TYPO3 records, e.g.
|
We will start with a very basic plugin that will display a hardcoded string.
|
||||||
`fe_users`.
|
|
||||||
|
|
||||||
Register Plugin in Backend
|
Register Plugin in Backend
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _configuration:
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
@ -45,12 +47,12 @@ TypoScript
|
||||||
|
|
||||||
TypoScript and Flexforms are merged by Extbase, so you do not have to do any
|
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
|
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.
|
``$this->settings`` out of the box.
|
||||||
|
|
||||||
.. admonition:: Task
|
.. 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:
|
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.
|
The whole ``settings`` array is passed into all templates, layouts and partials.
|
||||||
This way it's possible for integrators to provide arbitary information.
|
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
|
Also it's possible to insert a plugin via TypoScript. In that case the settings can
|
||||||
be provided only for that instance:
|
be provided only for that instance:
|
||||||
|
|
||||||
|
@ -113,9 +129,10 @@ be provided only for that instance:
|
||||||
Flexforms
|
Flexforms
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
Flexforms are like TCA, which will be covered later on. The format is XML instead of
|
Flexforms are like TCA, which will be covered at :ref:`custom-records-tca` section of
|
||||||
PHP and saved inside the database field ``pi_flexform`` of the ``tt_content`` record.
|
:ref:`custom-records`. The format is XML instead of PHP and saved inside the database
|
||||||
This way editors are able to adjust provided settings within a plugin record.
|
field ``pi_flexform`` of the ``tt_content`` record. This way editors are able to
|
||||||
|
adjust provided settings within a plugin record.
|
||||||
|
|
||||||
Custom
|
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
|
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
|
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
|
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
|
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
|
exists. Things like API Keys might depend on the current Domain or Website, and there
|
||||||
can be multiple in a single TYPO3 instance.
|
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
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
.. _custom-records:
|
||||||
|
|
||||||
Custom records
|
Custom records
|
||||||
==============
|
==============
|
||||||
|
|
||||||
The basics are behind us, now let's get deeper into the system and create a new
|
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.
|
record type, like ``tt_address`` which can be displayed through our plugin.
|
||||||
|
|
||||||
|
.. _custom-records-tca:
|
||||||
|
|
||||||
TCA
|
TCA
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -24,7 +28,7 @@ information are available there.
|
||||||
|
|
||||||
One thing to notice is that Extbase uses "Convention over Configuration". While we
|
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
|
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
|
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.
|
||||||
|
|
||||||
|
@ -62,7 +66,7 @@ ext_tables.sql
|
||||||
|
|
||||||
Once the TCA is provided, we need to create the table in our Database.
|
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
|
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.
|
current necessary structure of all extensions.
|
||||||
|
|
||||||
If multiple extensions adjust the same field, the last one in load order is used.
|
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
|
.. literalinclude:: ../../CodeExamples/localPackages/example_extension/ext_tables.sql
|
||||||
:language: 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
|
Model
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,6 @@ or via composer.
|
||||||
Oldschool
|
Oldschool
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
.. todo::
|
|
||||||
|
|
||||||
Add note about autoloading.
|
|
||||||
|
|
||||||
Copy the extension to :file:`typo3conf/ext/`, and head over to *Extension Manager* to
|
Copy the extension to :file:`typo3conf/ext/`, and head over to *Extension Manager* to
|
||||||
activate the extension.
|
activate the extension.
|
||||||
|
|
||||||
|
|
|
@ -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 API configures the TCA (=Table Configuration Array) for ``tt_content``. And adds
|
||||||
the new plugin as ``list_type``.
|
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
|
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
|
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
|
returned, which is ``null`` Extbase will try to find and render a template matching
|
||||||
our current controller and action. This is done at
|
our current controller and action. This is done at
|
||||||
``TYPO3\CMS\Extbase\Mvc\Controller\ActionController::callActionMethod``.
|
``\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::callActionMethod``.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _views:
|
||||||
|
|
||||||
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
|
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
|
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
|
Sections
|
||||||
--------
|
--------
|
||||||
|
|
||||||
If templates grow in size, we need to add some structure. One way is to use 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:
|
called with arguments:
|
||||||
|
|
||||||
.. code-block:: html
|
.. code-block:: html
|
||||||
|
@ -114,12 +117,12 @@ Assigned variables can be accessed inside Fluid with curly braces:
|
||||||
ViewHelper
|
ViewHelper
|
||||||
----------
|
----------
|
||||||
|
|
||||||
To make Templates more flexible, ViewHelpers are available. They are custom HTML-Tags
|
To make templates more flexible, ViewHelpers are available. They are custom HTML-Tags
|
||||||
available inside via template engine.
|
available inside the template engine.
|
||||||
TYPO3 and Fluid already ship some ViewHelpers, but you can provide own ViewHelpers.
|
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
|
ViewHelpers always live in a Namespace, e.g. ``\TYPO3\CMS\Fluid\ViewHelpers`` or
|
||||||
``Workshop\\ExampleExtension\\ViewHelpers``.
|
``\Workshop\ExampleExtension\ViewHelpers``.
|
||||||
|
|
||||||
You can either register these namespaces globally, or inside the templates via
|
You can either register these namespaces globally, or inside the templates via
|
||||||
``{namespace wee=Workshop\ExampleExtension\ViewHelpers}``.
|
``{namespace wee=Workshop\ExampleExtension\ViewHelpers}``.
|
||||||
|
@ -144,17 +147,17 @@ notation":
|
||||||
.. code-block:: html
|
.. code-block:: html
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
{f:format.date(date: 'now')}
|
{f:format.date(date: 'midnight')}
|
||||||
|
|
||||||
It's also possible to chain ViewHelpers in both ways:
|
It's also possible to chain ViewHelpers in both ways:
|
||||||
|
|
||||||
.. code-block:: html
|
.. code-block:: html
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
{f:format.date(date: 'now') -> f:format.raw()}
|
{f:format.date(date: 'midnight') -> f:format.raw()}
|
||||||
|
|
||||||
<f:format.raw>
|
<f:format.raw>
|
||||||
{f:format.date(date: 'now')}
|
{f:format.date(date: 'midnight')}
|
||||||
</f:format.raw>
|
</f:format.raw>
|
||||||
|
|
||||||
<f:format.raw>
|
<f:format.raw>
|
||||||
|
@ -171,7 +174,7 @@ Partials and Layouts
|
||||||
We already saw sections to make a single template easier to manage.
|
We already saw sections to make a single template easier to manage.
|
||||||
For re-using parts between multiple templates there are Partials.
|
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
|
.. code-block:: html
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
|
@ -12,7 +12,7 @@ Some "rules" for the workshop
|
||||||
* We will not call APIs without checking out their code. Always understand what your
|
* We will not call APIs without checking out their code. Always understand what your
|
||||||
own code does.
|
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.
|
work from 4.5 onwards.
|
||||||
|
|
||||||
* Ask questions as soon as possible. This way we have the context.
|
* Ask questions as soon as possible. This way we have the context.
|
||||||
|
|
Loading…
Reference in a new issue