Hello guys,
I'm new to Contao, I would appreciate a little help because I'm a little bit lost.
I'm trying to build a page where we would have a list of items and when you click on the item it would open the details.
I've created the autoload :
PHP Code:
ClassLoader::addClasses(array
(
    
'Contao\ItemModel'     => 'system/modules/item/models/ItemModel.php',

    
// Modules
    
'Contao\ModuleItemList' => 'system/modules/item/modules/ModuleItemList.php',
    
'Contao\ModuleItem'    => 'system/modules/item/modules/ModuleItem.php',

));


/**
 * Register the templates
 */
TemplateLoader::addFiles(array
(
    
'mod_item_list' => 'system/modules/item/templates',
    
'mod_details_item' => 'system/modules/item/templates',
)); 
The Config.php where register the front end modules
PHP Code:
/**
 * Back end modules
 */
$GLOBALS['BE_MOD']['content']['item'] = array
(
    
'tables' => array('tl_item'),
    
'icon'   => 'system/modules/item/assets/images/icon.png'
);

$GLOBALS['FE_MOD']['item'] = array
(
    
'item_list'     => 'ModuleItemList',
    
'details_item' => 'ModuleItem',
);

$GLOBALS['TL_MODELS']['tl_item'] = 'ItemModel' 

Created the dca file:
PHP Code:
<?php



/**
 * Table tl_screencast
 */
$GLOBALS['TL_DCA']['tl_item'] = array
(
 
    
// Config
    
'config'   => array
    (
        
'dataContainer'    => 'Table',
        
'enableVersioning' => true,
        
'sql'              => array
        (
            
'keys' => array
            (
                
'id' => 'primary'
            
)
        ),
    ),
    
    
// List
    
'list'     => array
    (
        
'sorting'           => array
        (
            
'mode'        => 2,
            
'fields'      => array('item'),
            
'flag'        => 1,
            
'panelLayout' => 'filter;sort,search,limit'
        
),
    
    
    
'label'             => array
        (
            
'fields' => array('item'),
            
'format' => '%s',
        ),
    
    
    
'global_operations' => array
        (
            
'all' => array
            (
                
'label'      => &$GLOBALS['TL_LANG']['MSC']['all'],
                
'href'       => 'act=select',
                
'class'      => 'header_edit_all',
                
'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"'
            
)
        ),
    
    
    
'operations'        => array
        (
            
'edit'   => array
            (
                
'label' => &$GLOBALS['TL_LANG']['tl_item']['edit'],
                
'href'  => 'act=edit',
                
'icon'  => 'edit.gif'
            
),
            
'delete' => array
            (
                
'label'      => &$GLOBALS['TL_LANG']['tl_item']['delete'],
                
'href'       => 'act=delete',
                
'icon'       => 'delete.gif',
                
'attributes' => 'onclick="if(!confirm(\'' $GLOBALS['TL_LANG']['MSC']['deleteConfirm'] . '\'))return false;Backend.getScrollOffset()"'
            
),
            
'show'   => array
            (
                
'label'      => &$GLOBALS['TL_LANG']['tl_item']['show'],
                
'href'       => 'act=show',
                
'icon'       => 'show.gif',
                
'attributes' => 'style="margin-right:3px"'
            
),
        )
    ),
    
    
// Palettes
    
'palettes' => array
    (
        
'default'       => '{title_legend},type,title,{item_legend},item,item2,adresse,ort,land,url,produkte,email,singleSRC'
    
),

    
    
// Fields
    
'fields'   => array
    (
        
'id'      => array
        (
            
'sql' => "int(10) unsigned NOT NULL auto_increment"
        
),
        
'tstamp' => array
        (
            
'sql' => "int(10) unsigned NOT NULL default '0'"
        
),
    
        
'item'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['item'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'mandatory' => true,
                
'unique'    => true,
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
    
        
'item2'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['item2'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
    
        
'adresse'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['adresse'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
    
        
'ort'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['ort'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
                
        
'land'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['land'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
    
        
'url'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['url'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
    
        
'produkte'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['produkte'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
    
        
'email'  => array
        (
            
'label'     => &$GLOBALS['TL_LANG']['tl_item']['email'],
            
'inputType' => 'text',
            
'exclude'   => true,
            
'sorting'   => true,
            
'flag'      => 1,
            
'search'    => true,
            
'eval'      => array(
                
'maxlength' => 255,
                
'tl_class'  => 'w50'
            
),
            
'sql'       => "varchar(255) NOT NULL default ''"
        
),
        
'target' => array
        (
            
'label'                   => &$GLOBALS['TL_LANG']['MSC']['target'],
            
'exclude'                 => true,
            
'inputType'               => 'checkbox',
            
'eval'                    => array('tl_class'=>'w50 m12'),
            
'sql'                     => "char(1) NOT NULL default ''"
        
),
    
        
'singleSRC' => array
        (
            
'label'                   => &$GLOBALS['TL_LANG']['tl_content']['singleSRC'],
            
'exclude'                 => true,
            
'inputType'               => 'fileTree',
            
'eval'                    => array('filesOnly'=>true'extensions'=>Config::get('validImageTypes'), 'fieldType'=>'radio''mandatory'=>true),
            
'sql'                     => "binary(16) NULL"
        
),
    
    )
);
Created the model
PHP Code:
<?php

namespace Contao;

class 
ItemModel extends \Model{
    
/**
     * Table name
     * @var string
     */
    
protected static $strTable 'tl_item';



    public static function 
countItem()
    {
        return 
count(static::findAll());


    }
    public static function 
findPublishedByIds$intLimit=0$intOffset=0)
    {

        
$t = static::$strTable;
        
$arrColumns = array("$t.id ");

        
$arrOptions['limit']  = $intLimit;
        
$arrOptions['offset'] = $intOffset;

        return static::
findBy($arrColumnsnull$arrOptions);
    }



}
Created the two modules:
PHP Code:
<?php

namespace Contao;

class 
ModuleItemList extends \Module
{
    
/**
     * Template
     * @var string
     */
    
protected $strTemplate 'mod_item_list';

    public function 
generate()
    {
        return 
parent::generate(); // TODO: Change the autogenerated stub
    
}

    
/**
     * Compile the current element
     */
    
protected function compile()
    {
        
        global 
$objPage;

        
// Daten aus der Datenbank laden
        
$total = \ItemModel::countItem();

        
// Pagination Template generieren
        
if ($this->perPage >= 0) {

            
$id 'page_e' $this->id;
            
$page = (Input::get($id) !== null) ? Input::get($id) : 1;

            if (
$page || $page max(ceil($total $this->perPage), 1)) {
                
$objHandler = new $GLOBALS['TL_PTY']['error_404']();
                
$objHandler->generate($objPage->id);
            }

            
$offset = ($page 1) * $this->perPage;
            
$limit min($this->perPage $offset$total);

            
$objPagination = new Pagination($total$this->perPageConfig::get('maxPaginationLinks'), $id);
            
$this->Template->pagination $objPagination->generate("\n  ");


        }
        
$objItem = \ItemModel::findPublishedByIds($limit$offset);

        
$arrItems = array();
        
$i 0;
        while(
$objItem->next()){
              
$objItem->link $this->generateFrontendUrl($objItem->row(), '/items/'$objItem->id);
            }
        

        }



       
$this->Template->item $objItem;




    }


}
The details module:
PHP Code:
<?php

namespace Contao;

class 
ModuleItem extends \Module
{
    
/**
     * Template
     * @var string
     */
    
protected $strTemplate 'mod_details_item';

    public function 
generate()
    {
        return 
parent::generate(); // TODO: Change the autogenerated stub
    
}

    
/**
     * Compile the current element
     */
    
protected function compile()
    {

        
$objCd = \ModuleItem::findByPk(\Input::get('items'));
       
        global 
$objPage;

    }


}

And then generated the html templates:
PHP Code:
<?php $this->extend('block_searchable'); ?>
<?php $this
->block('content'); ?>
     <?php foreach ($this->item as $detail): ?>

             <a href="<?php echo $detail->link?>">
                <?php echo $detail->id?>
             </a>
             <br>
       <?php endforeach;  ?>
    <?php echo $this->pagination?>


<?php $this->endblock(); ?>
and the details:
PHP Code:
<div class="layout_full block">
<?php echo->id?>


</div>
The list is good with the pagination I have everything but when I click on the link it generates a page not found, How does contao link both pages? Thanks in advance