Translations
Info
All page names need to be in English.
en da  de  fr  it  ja  km  nl  ru  zh

Apples

From TYPO3Wiki
Jump to: navigation, search

notice - Note

The lib/div extensions are not actively maintained and should be considered deprecated!!
This page belongs to the Extension coordination team (category ECT)

Apples "Hello World"

Entering the garden of real object orientated extension development

The extension is the Hello World example of lib/div development. Take your first walk into the garden of real object orientated extension design. After a few steps you will harvest your first apples by the use of a model, a view and a controller class. You will get a basic feeling for the MVC architecture and you will long for more.

But be warned. Don't directly run into the garden on your own. You may get lost. The apple walk doesn't show you enough, that you could already build a useful extension. The garden is a good deal bigger than you would expect. Take the bananas tour next, to learn fundamental features, that are required by typical extensions: bananas By starting with the apples walk you will be able to keep track of the wide land of the bananas plantation.

Installation

Install the extension

Apples extension in the extension manager.

Go to the module Tools/Ext Manager and install the extension Apples (apples) in the typical way. You will discover that, it depends on the extension lib which again depends on div.


ECT extensions in the extension manager.

Include the static template

Go to the module Web/Template and open the template, where you want to configure the extension, in the Info/Modify view. In the select box Include static (from extensions) you select the template Apples (apples). Save it.

Include the static template.

Use the plugin

Go to the module Web/Page and open a page. Insert in the Apples plugin. Save it. In the frontend you should now find a description of the apple Belle de Boskoop.

Apples frontend view.

Building your own

This isn't a step by step tutorial. It's up to you, how you want to use the given material.

As a step by step tutorial

You can use this extension just like a step by step tutorial. Although there are several files, there is only a small amount code. You copy or type each file (maybe with a different key) to see how it works. Start with the files in the base directory and with the configuration (setup) and the controller directories. When you have managed to call the controller as a plugin, you add model and view.

Playing with the code

You can also take this extension and play with it. You could extend the model, trying other rendering engines or implement a second plugin into the same extension.

Start your own extension

If you don't want to use extension kickstarter__mvc, you could use this extension to get started, with a new project. You replace all occurances of the string apples against your own extension key in the files and in the filenames. Please choose an extension key without underscores.

The structure of the file system

The interesting files of the plugin:

 ext_emconf.php
 ext_icon.gif
 ext_localconf.php
 ext_tables.php
 configuration/setup.txt
 controllers/class.tx_apples_controllers_example.php
 models/class.tx_apples_models_example.php
 templates/example.php
 views/class.tx_apples_views_example.php

General considerations

There is only one plugin in this example. If you work with multiple plugins, there are 2 different styles to organize the files. The first is to place all files of a plugin into a common folder. The second is to group the files by functionality (configuration, controllers, models, ...). That's what we do in this example. Feel free to discover your own style.

The base directory

While you are free in general to structure the whole extension as you like, a few files are required to exist in the base directory, namely the files ext_emconf.php and ext_icon.gif. Other files of the base directory are optional. Some files of a given name have a special function when available. In our example this are the files ext_localconf.php and ext_tables.php. All this files are used in their typical way for TYPO3 extensions.

The directory configuration

The directory configuration contains the file setup.txt. In bigger extensions it would contain other configurations, maybe subdirectories. At the same time this directory is the static template that is registered in the file ext_tables.php

with the line:
PHP script:
t3lib_extMgm::addStaticFile('apples', './configuration', 'Apples');     // ($extKey, $path, $title)

If you like to work with multiple static templates in a big extension, you could register subdirectories of the configuration directory.

The directory controllers

As the name implies, controllers are the classes that control the cooperation of models and views. Typically, each plugin has one controller class so we find one class in this directory.

The directory models

The name models tells you that these classes contains the data, that will be displayed by the 'view'. In the case of apples this data will be simply contained within the single class of the 'model'. In more useful extensions, you will also place the functional logic, including database queries, into the 'model'. In enterprise environments, you would use the 'model' to delegate the business logic to other servers.

The directory templates

This directory contains the templates of the view. This is the interface between the programmers and the web designers. You can configure the path to this directory in the setup, so that the web designers could place the templates into other locations like the fileadmin/ folder.

Depending on the rendering engine you choose, you can use different types of templates. Apples uses the PHP-rendering engine. You could choose templates in traditional TYPO3 style or Smarty templates, if you add the matching template engine.

The directory views

In this directory the classes are stored that handle the templates. They implement a type of a rendering engine.

File list of the apples extension.

Including files

There are different ways to require class files, some inclusions are done magically, when you instance a class. Before you can use the the magic functions of tx_div you have to include it.

This is done the traditional T3 way in the class ext_localconf.php:
PHP script:
  require_once(t3lib_extMgm::extPath('div') . 'class.tx_div.php');
In the same file you find the line:
PHP script:
  if(TYPO3_MODE == 'FE') tx_div::autoLoadAll($_EXTKEY);

This includes all classes of the given extension and works for apples. But it has some drawbacks. Please read the documentation of tx_div::autoLoadAll() before using it in your

extension. To mention the typical way of lib/div file inclusion:
PHP script:
  tx_div::load('tx_apples_controllers_example');

There is no example in appples for this, because it's coverd by the autoLoadAll() method.

Finally you could include files in the setup, which would look like this:
TS TypoScript:
  includeLibs.tx_div = EXT:div/class.tx_div.php
  includeLibs.tx_apples_controllers_example = EXT:apples/controllers/class.tx_apples_controllers_example.php

Including files magically

In the file controllers/class.tx_apples_controllers_example.php you find the following lines:
PHP script:
  $modelClassName = tx_div::makeInstanceClassName('tx_apples_models_example');
  $viewClassName = tx_div::makeInstanceClassName('tx_apples_views_example');

The use of the function tx_div::makeInstanceClassName() is in line with the TYPO3 Coding Guidelines. The effect is to check if an XCLASS is defined for the given classname. In this case it is used. Additionally the call to tx_div::makeInstanceClassName() magically requires class files with classnames following the lib/div syntax.

In your private extensions you may drop the use of makeInstanceClassName if you are sure that you don't want to use the XCLASS feature. Then you have to take other measures to assure the files are included.

Similar considerations apply to the the function tx_div::makeInstance(), that is not used in apples.

Calling the controller

The most difficult part to get started is the inclusion of the controller as a plugin.

When a page is called, that contains the plugin the controller of that plugin has to be called. The controller then runs the job, coordinates model and view and returns a chunk of XHTML to display in the page.

This call of a controller by a plugin is configured in the file configurations/setup.txt.
TS TypoScript:
  plugin.tx_apples.exampleController = USER_INT
  plugin.tx_apples.exampleController.userFunc = tx_apples_controllers_example->main
  [... adding configurations ...]
  tt_content.list.20.tx_apples_example =< plugin.tx_apples.exampleController

During installation you have to manually include this static template from the list of static templates.

To list it, you have to register the static template in the file ext_tables.php.
PHP script:
  t3lib_extMgm::addStaticFile('apples', './configuration', 'Apples');     // ($extKey, $path, $title)
Also in ext_tables the plugin has to be registered for the BE forms.
PHP script:
  t3lib_extMgm::addPlugin(array('Apples', 'tx_apples_example'));          // array($title, $pluginKey)

The plugin key is necessary to match the input of the BE forms with the output by typoscript. The plugin key should start with the extension key (best with tx_-prefix) to avoid conflicts. You could consider to always use the classname of the controller unlike the 'Apples' example.

The static template in the template analyzer.

Configurations

Apart from the inclusion of the controller, also the configurations are done

in the file configurations/setup.txt.
TS TypoScript:
  [...]
  // Setting configurations
  plugin.tx_apples.exampleController.templatePath = EXT:apples/templates/
  plugin.tx_apples.exampleController.exampleTemplate = example.php
  [...]
  tt_content.list.20.tx_apples_example =< plugin.tx_apples.exampleController

In this example we assign the path to the templates to the key templatePath. The assignment of the templatePath is required!!! You can use the EXT: syntax. Additionally we assign a template file to the key exampleTemplate.

For productive extensions you often set dozends of key value pairs, that can be configured as constants in turn. All configurations that are defined this way, are automatically filled into the configurations object $this->controller->configurations of the plugin.

Controller

The controller in the VIM editor.


The controller extends the class tx_lib_controller.
PHP script:
  class tx_apples_controllers_example extends tx_lib_controller{
The example works with one action only, so it is defined as the default action.
PHP script:
  var $defaultAction = 'exampleAction';
This is the default action:
PHP script:
  function exampleAction() {
    $modelClassName = tx_div::makeInstanceClassName('tx_apples_models_example');
    $viewClassName = tx_div::makeInstanceClassName('tx_apples_views_example');
    $view = new $viewClassName($this, new $modelClassName($this)); 
    return $view->render($this->configurations->get('exampleTemplate'));
  }

First the model is instanced. Once the model is instantiated, it will be initialized with the data.

It can directly be given to the views constructor.
PHP script:
  $view = new $viewClassName($this, new $modelClassName($this));

The view is rendered and the final result is returned to the calling framework. When the view is rendered, it expects the name of the template as a parameter,

wich we take from the configurations object.
PHP script:
  return $view->render($this->configurations->get('exampleTemplate'));

The configuration object is created automatically when the main function of the controller is called by the outer T3 framework. By default the view uses the configuration value of templatePath to determine the template path.

Model

The model in the VIM editor.

The model extends the class tx_lib_object.
PHP script:
  class tx_apples_models_example extends tx_lib_object {
    function tx_apples_models_example() {
      parent::tx_lib_object();
      $this->set('name', 'Belle de Boskoop');
      $this->set('orign', 'Boskoop, Netherlands');
      $this->set('use', 'cooking (traditionally: apple sauce)');
      $this->set('comment', 'bright red, fairly large, early in season (end of august-early september)');
      $this->set('amount', 10);
      $this->set('price', 1.75);
    }
  }

Already the constructor fills up this object with the data.

View

The view extends the class tx_lib_phpTemplateEngine.
PHP script:
  class tx_apples_views_example extends tx_lib_phpTemplateEngine {
  }

All functions that are needed within apples are inherited.

Template

The PHP template in the VIM editor.

The template is very simple to understand. Chunks of PHP code are embedded. $this always refers to the object of the view class, which is calling the template. The formatting functions like printAsText($key) are inherited from tx_lib_phpTemplateEngine().

They give some power of choice to the template designer.
PHP script:
  <?php $this->printAsText('name'); ?>
  [...]
  <?php $this->printAsInteger('amount'); ?>
  [...]
  <?php $this->printAsFloat('price'); ?>

Not everybody likes to give that much power and complexity to the template desigers. In this case you could prepare the necessary rendering of each date within the view class, so that the designer only needs to know one function call. You are also encouraged to use other rendering engines and templates for the view.