pattern

MVC - Part 2: "TYPO3 mvcnews example"

We have T3DD and its time to publish the new release of the "mvc" extension together with a first version of an example extension.

Introducing the example:

The extension "mvcnews" is planned as a normal news application with articles and categorys, articles can have comments and there can be downloads attached to the article.

The requirements to the frontend are common: We need a article overview with the features: searchform, pagination and resultlist. Also we need a detailview of an article. That should be all for now.

Model

So the domain model is pretty simple (only relevant parts are shown for now)


Controller

Like explained above we need two frontend outputs: a listview and a detailview. We put this both in one controller, that has two actions: "showlistAction()" and "showdetailAction()". Because the controller needs to access articles, it needs at least the articleRepository. With dependency injection its the best to let the articleRepository inject into the controller.

With that its pretty easy to fill the showdetailAction with live: Its straight forward: 1. ask the repository for the article that should be displayed
2. pass it to the view, and return the view result.

/**
* detail action shows the single view of an object, if a detail view of an object is
* requested.
*
* @return string
*/
public function showdetailAction() {
if (empty ( $this->arguments ['id'] )) {
throw new InvalidArgumentsExcepton('no valid id given');
}
$this->view->setArticle ( $this->articleRepository->findById ( $this->arguments ['id'] ) );
return $this->view->render ();
}

The detail view

Like shown above there needs to be a view that is able to render an article. And the view - of course - has to know the article it should render. Therefore the view has a "setArticle" method to set the article the view should render.

Our detail view actually implements the phpTemplateView, so a template that belongs to that view can look like that:



<div id="objects">
<h2><?php echo $this->article->getTitle();  ?></h2>
<p><small><?php echo
$this->labels->get('field_category'); ?>:<?php echo
$this->article->getCategory()->getTitle();
?></small></p>
      
 <p><small><?php echo
$this->labels->get('field_date'); ?>:<?php echo
$this->article->getDate(); ?></small></p>
<div class="image">
<?php     echo $this->article->getImage();   ?>
</div>
<?php     echo $this->article->getDescription();   ?>
</div>

There is one thing thats not perfect: In the view I expect that the getImage returns a Imagetag, and that the description is processed by the TYPO3 parseFunc_RTE stuff.  There are two ways to solve that:

  1. we could use viewhelpers (like $this->fieldRenderer->asImage(...)) to transform the imagepath to a imagetag for example.
  2. we can use a presentationmodel and do the transformation of fields for the view there.

(Btw.: we should not add logic to the domain model, because a imagetag is purely view related and has no meaning in the domain)

We decide to go with version 2 - just because we might need this transformation in the listview again.

The mvc framework offers a TCA presentationmodel, that does most of the transformations magic with the help of the TCA informations, so we just need to wrap a presentationmodel around our article object:

new tx_mvcnews_presentation_articlePresentationModel ( $this->articleRepository->findById ( $this->arguments ['id'] ), $this->configuration->get ( 'presentationModel.article.' ), 'tx_mvcnews_article' );

The showlistAction and the listview:

For the listview we need to find a clean and flexible solution to:

  1. get the correct collection of articles, that matches the search
  2. render the output with: searchform, pagination and actual results.

For the first problem we use a seperate searchCriteriaObject, that has all the informations for the current search - this object is build from the current arguments. Then we pass the searchCriteria to the articleRepository->findByCriteria method and all the application-specific searchlogic has to be part of this repository. So the call sequenz  looks something like this:


For the second problem we use the pattern compositeView. Thats mainly a view that consits of other views - and just like the requirements say: we have three subviews: pagination, searchform and list. Of course all of this subviews require a model that they can render:

  • the paginationSubView has setter methods to provide the required informations for the pagination
  • the searchformSubView - well it needs a formmodel. The formmodel tells the searchForm which formelements it can render. The seperate formmodel is also greate to validate the users input before doing anything.
  • and finaly the listSubView needs the collection of articles that it should render.

The main advantage of splitting your view into subviews is that you can reuse the views. So imagine you need the searchform as a standalone form, or you might need just the list of lastest articles -> you can reuse the existing views.


This is how the class diagramm of the listview looks like:


And finaly this is the output:


Whats next?

You can have a look in the example extension and see yourself how it works.

By now the example "mvcnews" has just a basic output without any advanced features, here is whats planned next:

  • add AJAX loading for searching and paginating
  • add more features like commenting and rating, that propably results in a richer domain model and more action methods in the controller.

blog comments powered by Disqus
  1. Len 16.09.11 11:18

    As I see all your articles are informative and full of valuable information so I will definitely bookmark your website and wait for more such great posts like this one.
    admissions essay

  2. Martin 06.03.11 00:17

    Great article, helped me alot with the understanding of the problem.
    Kontorshotell Göteborg

  3. Muhammad Ali 24.10.10 05:53

    we could use viewhelpers (like $this->fieldRenderer->asImage(...)) to transform the imagepath to a imagetag for example.
    Flyttstädning Stockholm

  4. mivpl 30.07.10 08:55

    TYPO3 5.0, which is not yet available, will fully support the MVC approach to object-oriented programming.link building service

  5. Tschüge http://www.greenbanana.ch 15.08.09 16:32

    Hallo,

    Ich bin dabei ein Ticketsystem mit extbase zu erstellen. Weiss jemand wie ich die Funktion: sql_inser_id() mit extbase verwenden kann?

    Habe die Frage auch schon im Forum gestellt:
    http://www.typo3.net/forum/list/list_post//92124/?page=1#pid337767

    Gruss und danke für eventuelle Hilfe.

    Gruss
    Tschüge

  6. zenghui 20.07.09 13:58

  7. runescape money http://www.rs-sky.com 02.06.09 08:33

    Hi there,
    Ugh, I liked! So clear and positively.
    Have a nice day

  8. growthflex 02.06.09 06:58

    hi i rad this article thank you for this great information..

  9. Daniel 01.06.09 20:20

    Hey

    It shares the same concepts (MVC, persitence, Domain Driven Design) - but it used a diffrent Framework (not extBase but mvc).

    And for migration to TYPO3 5.0 it should be the same as for extBase extensions: If you allready have functionality in a clean (domain) model - its more or less renaming and refactoring to get it work with FLOW3.

  10. Sebastian 26.05.09 20:59

    How does this MVC extension relates to extBase coming with next release 4.3 or how does it integrates later with TYPO3 5.0/FLOW3?

blogroll